Release 6.1.7

This commit is contained in:
Bo Chen
2021-06-02 06:45:05 +00:00
parent d759e6bb9e
commit f5056f4923
1269 changed files with 57325 additions and 55178 deletions

View File

@@ -0,0 +1,153 @@
<?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.1186660388">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.exe.debug.1186660388" 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.1186660388" name="Debug" parent="com.arm.eclipse.build.config.v6.exe.debug" postbuildStep="">
<folderInfo id="com.arm.eclipse.build.config.v6.exe.debug.1186660388." name="/" resourcePath="">
<toolChain id="com.arm.toolchain.v6.exe.debug.2059027187" name="Arm Compiler 6 (DS-5 built-in)" superClass="com.arm.toolchain.v6.exe.debug">
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.toolchain.v6.base.options.debug.level.217899897" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" useByScannerDiscovery="false" valueType="enumerated"/>
<option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.1952359845" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" useByScannerDiscovery="false" value="Cortex-R4.VFPv3_D16" valueType="string"/>
<option id="com.arm.toolchain.v6.base.options.floatabi.2083363025" name="Float ABI" superClass="com.arm.toolchain.v6.base.options.floatabi" useByScannerDiscovery="false" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
<option id="com.arm.toolchain.v6.base.options.inst.214405138" name="Instruction set" superClass="com.arm.toolchain.v6.base.options.inst" useByScannerDiscovery="false" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
<targetPlatform id="com.arm.eclipse.build.config.v6.exe.debug.1186660388..1840465310" name=""/>
<builder buildPath="${workspace_loc:/sample_threadx_module}/Debug" id="com.arm.toolchain.v6.builder.712205487" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.arm.toolchain.v6.builder"/>
<tool id="com.arm.tool.c.compiler.v6.2054850494" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.min" id="com.arm.tool.c.compiler.v6.base.option.optlevel.1593499563" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.tool.c.compiler.v6.base.options.debug.level.558177784" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" valueType="enumerated"/>
<option id="com.arm.tool.c.compiler.v6.base.option.cpu.1528797782" name="CPU (-mcpu)" superClass="com.arm.tool.c.compiler.v6.base.option.cpu" useByScannerDiscovery="true" value="cortex-r4f" valueType="string"/>
<option id="com.arm.tool.c.compiler.v6.base.option.target.2107191754" 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.fpu.701656758" name="FPU (-mfpu)" superClass="com.arm.tool.c.compiler.v6.base.option.fpu" useByScannerDiscovery="true" value="vfpv3-d16" valueType="string"/>
<option id="com.arm.tool.c.compiler.v6.base.option.floatabi.271588144" 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.1826434500" 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 id="com.arm.tool.c.compiler.v6.base.option.incpath.1401908599" name="Include path (-I)" superClass="com.arm.tool.c.compiler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/txm/inc_generic}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/txm/inc_generic_modules}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/txm/inc_port}&quot;"/>
</option>
<option id="com.arm.tool.c.compiler.v6.base.option.flags.121551369" name="Other flags" superClass="com.arm.tool.c.compiler.v6.base.option.flags" useByScannerDiscovery="true" valueType="stringList">
<listOptionValue builtIn="false" value="-fropi"/>
<listOptionValue builtIn="false" value="-frwpi"/>
</option>
<option id="com.arm.tool.c.compiler.v6.base.options.target.enableToolSpecificSettings.1260481240" name="Enable tool specific settings" superClass="com.arm.tool.c.compiler.v6.base.options.target.enableToolSpecificSettings" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<inputType id="com.arm.tool.c.compiler.v6.base.input.294190860" superClass="com.arm.tool.c.compiler.v6.base.input"/>
<inputType id="com.arm.tool.cpp.compiler.v6.base.input.1360199906" superClass="com.arm.tool.cpp.compiler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.cpp.compiler.v6.22094800" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.min" id="com.arm.tool.c.compiler.v6.base.option.optlevel.1119785101" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.tool.c.compiler.v6.base.options.debug.level.1584629976" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" valueType="enumerated"/>
</tool>
<tool id="com.arm.tool.assembler.v6.1445475633" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6">
<option defaultValue="com.arm.tool.assembler.v6.base.options.debug.level.std" id="com.arm.tool.assembler.v6.base.options.debug.level.1996877403" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" useByScannerDiscovery="false" valueType="enumerated"/>
<option id="com.arm.tool.assembler.v6.base.option.cpu.1169848349" name="CPU (-mcpu)" superClass="com.arm.tool.assembler.v6.base.option.cpu" useByScannerDiscovery="false" value="cortex-r4f" valueType="string"/>
<option id="com.arm.tool.assembler.v6.base.option.target.1621759525" 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.fpu.1052186290" name="FPU (-mfpu)" superClass="com.arm.tool.assembler.v6.base.option.fpu" useByScannerDiscovery="true" value="vfpv3-d16" valueType="string"/>
<option id="com.arm.tool.assembler.v6.base.option.floatabi.621797848" 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.669141109" 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.option.incpath.46636479" name="Include path (-I)" superClass="com.arm.tool.assembler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/txm}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/tx}&quot;"/>
</option>
<option id="com.arm.tool.assembler.v6.base.option.flags.1723710627" name="Other flags" superClass="com.arm.tool.assembler.v6.base.option.flags" useByScannerDiscovery="true" valueType="stringList">
<listOptionValue builtIn="false" value="-frwpi"/>
<listOptionValue builtIn="false" value="-fropi"/>
</option>
<inputType id="com.arm.tool.assembler.v6.base.input.705473083" superClass="com.arm.tool.assembler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.c.linker.v6.1069019142" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6">
<option id="com.arm.tool.c.linker.implicit.libs.411858467" name="Implicit other library files" superClass="com.arm.tool.c.linker.implicit.libs" useByScannerDiscovery="false" valueType="libs">
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="&quot;${workspace_loc:/txm/Debug/txm.a}&quot;"/>
</option>
<option id="com.arm.tool.c.linker.option.entry.2143658488" name="Image entry point (--entry)" superClass="com.arm.tool.c.linker.option.entry" useByScannerDiscovery="false" value="_txm_module_thread_shell_entry" valueType="string"/>
<option id="com.arm.tool.c.linker.option.predefine.1247653322" name="Predefine (--pd)" superClass="com.arm.tool.c.linker.option.predefine" useByScannerDiscovery="true"/>
<option id="com.arm.tool.c.linker.option.flags.1650736668" name="Other flags" superClass="com.arm.tool.c.linker.option.flags" useByScannerDiscovery="true" valueType="stringList">
<listOptionValue builtIn="false" value="--first txm_module_preamble.o"/>
<listOptionValue builtIn="false" value="--ro 0x00100000"/>
<listOptionValue builtIn="false" value="--ropi"/>
<listOptionValue builtIn="false" value="--rwpi"/>
</option>
<option id="com.arm.tool.c.linker.option.redirectoutput.208933002" name="Redirect diagnostics output to file (--list)" superClass="com.arm.tool.c.linker.option.redirectoutput" useByScannerDiscovery="false" value="" valueType="string"/>
<option id="com.arm.tool.c.linker.option.sizes.1595432024" name="List code and data sizes of output image (--info=sizes)" superClass="com.arm.tool.c.linker.option.sizes" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="com.arm.tool.c.linker.option.elim.1398313860" name="List unused sections that are eliminated (--info=unused)" superClass="com.arm.tool.c.linker.option.elim" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="com.arm.tool.c.linker.option.totals.1098945540" name="List total code and data sizes of output image (--info=totals)" superClass="com.arm.tool.c.linker.option.totals" useByScannerDiscovery="false" value="true" valueType="boolean"/>
</tool>
<tool id="com.arm.tool.librarian.v6.17867471" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings">
<externalSettings containerId="tx;" factoryId="org.eclipse.cdt.core.cfg.export.settings.sipplier">
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/tx"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/tx/Debug"/>
<entry flags="RESOLVED" kind="libraryFile" name="tx" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
<externalSettings containerId="txm;" factoryId="org.eclipse.cdt.core.cfg.export.settings.sipplier">
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/txm"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/txm/Debug"/>
<entry flags="RESOLVED" kind="libraryFile" name="txm" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
</storageModule>
</cconfiguration>
<cconfiguration id="com.arm.eclipse.build.config.v6.exe.release.1059742195">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.exe.release.1059742195" 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.1059742195" name="Release" parent="com.arm.eclipse.build.config.v6.exe.release">
<folderInfo id="com.arm.eclipse.build.config.v6.exe.release.1059742195." name="/" resourcePath="">
<toolChain id="com.arm.toolchain.v6.exe.release.193865725" name="Arm Compiler 6 (DS-5 built-in)" superClass="com.arm.toolchain.v6.exe.release">
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.toolchain.v6.base.options.debug.level.245795922" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" valueType="enumerated"/>
<targetPlatform id="com.arm.eclipse.build.config.v6.exe.release.1059742195..238205684" name=""/>
<builder buildPath="${workspace_loc:/sample_threadx_module}/Release" id="com.arm.toolchain.v6.builder.1520240122" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.arm.toolchain.v6.builder"/>
<tool id="com.arm.tool.c.compiler.v6.1225859893" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.high" id="com.arm.tool.c.compiler.v6.base.option.optlevel.1899903412" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.tool.c.compiler.v6.base.options.debug.level.348399030" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" valueType="enumerated"/>
<inputType id="com.arm.tool.c.compiler.v6.base.input.772104434" superClass="com.arm.tool.c.compiler.v6.base.input"/>
<inputType id="com.arm.tool.cpp.compiler.v6.base.input.422075046" superClass="com.arm.tool.cpp.compiler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.cpp.compiler.v6.879947257" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.high" id="com.arm.tool.c.compiler.v6.base.option.optlevel.1104950385" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.tool.c.compiler.v6.base.options.debug.level.176097568" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" valueType="enumerated"/>
</tool>
<tool id="com.arm.tool.assembler.v6.1910026527" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6">
<option defaultValue="com.arm.tool.assembler.v6.base.options.debug.level.none" id="com.arm.tool.assembler.v6.base.options.debug.level.891339047" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" valueType="enumerated"/>
<inputType id="com.arm.tool.assembler.v6.base.input.344668889" superClass="com.arm.tool.assembler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.c.linker.v6.20284280" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6"/>
<tool id="com.arm.tool.librarian.v6.775202115" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="sample_threadx_module.com.arm.eclipse.build.project.v6.exe.1790254349" name="Executable" projectType="com.arm.eclipse.build.project.v6.exe"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope"/>
<storageModule moduleId="com.arm.projectSettings" version="5.25"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
</cproject>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>sample_threadx_module</name>
<comment></comment>
<projects>
<project>tx</project>
<project>txm</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="com.arm.eclipse.build.config.v6.exe.debug.1186660388" 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="1218969334819235502" 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 &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
<configuration id="com.arm.eclipse.build.config.v6.exe.release.1059742195" 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="1208898303067000398" 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 &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>

View File

@@ -0,0 +1,425 @@
/* This is a small demo of the high-performance ThreadX kernel running as a module. It includes
examples of eight threads of different priorities, using a message queue, semaphore, mutex,
event flags group, byte pool, and block pool. */
/* Specify that this is a module! */
#define TXM_MODULE
/* Include the ThreadX module definitions. */
#include "txm_module.h"
/* Define constants. */
#define DEMO_STACK_SIZE 1024
#define DEMO_BYTE_POOL_SIZE 9120
#define DEMO_BLOCK_POOL_SIZE 100
#define DEMO_QUEUE_SIZE 100
/* Define the pool space in the bss section of the module. ULONG is used to
get the word alignment. */
ULONG demo_module_pool_space[DEMO_BYTE_POOL_SIZE / 4];
/* 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 = 0x12;
ULONG thread_1_counter = 0x34;
ULONG thread_2_counter = 0x56;
ULONG thread_3_counter = 0x78;
ULONG thread_4_counter = 0x9A;
ULONG thread_5_counter = 0xBC;
ULONG thread_6_counter = 0xDE;
ULONG thread_7_counter = 0xEF;
ULONG semaphore_0_puts;
ULONG event_0_sets;
ULONG queue_0_sends;
ULONG thread_1_messages_sent;
ULONG thread_2_messages_received;
/* 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);
void semaphore_0_notify(TX_SEMAPHORE *semaphore_ptr)
{
if (semaphore_ptr == semaphore_0)
semaphore_0_puts++;
}
void event_0_notify(TX_EVENT_FLAGS_GROUP *event_flag_group_ptr)
{
if (event_flag_group_ptr == event_flags_0)
event_0_sets++;
}
void queue_0_notify(TX_QUEUE *queue_ptr)
{
if (queue_ptr == queue_0)
queue_0_sends++;
}
/* Define the module start function. */
void demo_module_start(ULONG id)
{
CHAR *pointer;
/* Allocate all the objects. In MMU mode, modules cannot allocate control blocks within
their own memory area so they cannot corrupt the resident portion of ThreadX by overwriting
the control block(s). */
txm_module_object_allocate((void *) &thread_0, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &thread_1, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &thread_2, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &thread_3, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &thread_4, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &thread_5, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &thread_6, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &thread_7, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &queue_0, sizeof(TX_QUEUE));
txm_module_object_allocate((void *) &semaphore_0, sizeof(TX_SEMAPHORE));
txm_module_object_allocate((void *) &mutex_0, sizeof(TX_MUTEX));
txm_module_object_allocate((void *) &event_flags_0, sizeof(TX_EVENT_FLAGS_GROUP));
txm_module_object_allocate((void *) &byte_pool_0, sizeof(TX_BYTE_POOL));
txm_module_object_allocate((void *) &block_pool_0, sizeof(TX_BLOCK_POOL));
/* Create a byte memory pool from which to allocate the thread stacks. */
tx_byte_pool_create(byte_pool_0, "module byte pool 0", demo_module_pool_space, 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
tx_queue_send_notify(queue_0, queue_0_notify);
/* Create the semaphore used by threads 3 and 4. */
tx_semaphore_create(semaphore_0, "module semaphore 0", 1);
tx_semaphore_put_notify(semaphore_0, semaphore_0_notify);
/* Create the event flags group used by threads 1 and 5. */
tx_event_flags_create(event_flags_0, "module event flags 0");
tx_event_flags_set_notify(event_flags_0, event_0_notify);
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
tx_mutex_create(mutex_0, "module 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, "module 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;
/* Test external/shared memory. */
*(ULONG *) 0x08025000 = 0xdeadbeef;
/* 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;
}
}

View File

@@ -0,0 +1,27 @@
/* Disable semihosting */
#include <rt_sys.h>
#if (__ARMCC_VERSION < 6000000)
#pragma import(__use_no_semihosting)
#else
void use_no_semihosting(void)
{
__asm(".global __use_no_semihosting\n\t");
}
#endif
char *$Sub$$_sys_command_string(char *cmd, int len)
{
return 0;
}
__attribute__((noreturn)) void $Sub$$_sys_exit(int return_code)
{
while(1);
}
__attribute__((noreturn)) int $Sub$$__raise(int signal, int type)
{
while(1);
}

View File

@@ -0,0 +1,58 @@
.text
/* Define common external references. */
.global _txm_module_thread_shell_entry
.global demo_module_start
.global _txm_module_callback_request_thread_entry
.global Image$$ER_RO$$Length
.global Image$$ER_RW$$Length
.global Image$$ER_ZI$$ZI$$Length
/* Stack aligned, ROPI and RWPI, R9 used as data offset register. */
.eabi_attribute Tag_ABI_align_preserved, 1
.eabi_attribute Tag_ABI_PCS_RO_data, 1
.eabi_attribute Tag_ABI_PCS_R9_use, 1
.eabi_attribute Tag_ABI_PCS_RW_data, 2
__txm_module_preamble:
.word 0x4D4F4455 /* Module ID */
.word 0x6 /* Module Major Version */
.word 0x1 /* Module Minor Version */
.word 32 /* Module Preamble Size in 32-bit words */
.word 0x12345678 /* Module ID (application defined) */
.word 0x01000001 /* Module Properties where:
Bits 31-24: Compiler ID
0 -> IAR
1 -> RVDS/ARM
2 -> GNU
Bits 23-1: Reserved
Bit 0: 0 -> Privileged mode execution (no MMU protection)
1 -> User mode execution (MMU protection) */
.word _txm_module_thread_shell_entry - __txm_module_preamble /* Module Shell Entry Point */
.word demo_module_start - __txm_module_preamble /* Module Start Thread Entry Point */
.word 0 /* Module Stop Thread Entry Point */
.word 1 /* Module Start/Stop Thread Priority */
.word 1024 /* Module Start/Stop Thread Stack Size */
.word _txm_module_callback_request_thread_entry - __txm_module_preamble /* Module Callback Thread Entry */
.word 1 /* Module Callback Thread Priority */
.word 1024 /* Module Callback Thread Stack Size */
.word 9000 /* Module Code Size */
.word 11000 /* Module Data Size */
.word 0 /* Reserved 0 */
.word 0 /* Reserved 1 */
.word 0 /* Reserved 2 */
.word 0 /* Reserved 3 */
.word 0 /* Reserved 4 */
.word 0 /* Reserved 5 */
.word 0 /* Reserved 6 */
.word 0 /* Reserved 7 */
.word 0 /* Reserved 8 */
.word 0 /* Reserved 9 */
.word 0 /* Reserved 10 */
.word 0 /* Reserved 11 */
.word 0 /* Reserved 12 */
.word 0 /* Reserved 13 */
.word 0 /* Reserved 14 */
.word 0 /* Reserved 15 */

View File

@@ -0,0 +1,136 @@
<?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.779721393">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.exe.debug.779721393" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/sample_threadx"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/sample_threadx/Debug"/>
<entry flags="RESOLVED" kind="libraryFile" name="sample_threadx" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</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.779721393" name="Debug" parent="com.arm.eclipse.build.config.v6.exe.debug">
<folderInfo id="com.arm.eclipse.build.config.v6.exe.debug.779721393." name="/" resourcePath="">
<toolChain id="com.arm.toolchain.v6.exe.debug.103434698" name="Arm Compiler 6 (DS-5 built-in)" superClass="com.arm.toolchain.v6.exe.debug">
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.toolchain.v6.base.options.debug.level.122267120" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" useByScannerDiscovery="false" valueType="enumerated"/>
<option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.727798067" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" useByScannerDiscovery="false" value="Cortex-R4.VFPv3_D16" valueType="string"/>
<option id="com.arm.toolchain.v6.base.options.floatabi.1169109311" name="Float ABI" superClass="com.arm.toolchain.v6.base.options.floatabi" useByScannerDiscovery="false" value="com.arm.tool.c.compiler.v6.base.option.floatabi.hard" valueType="enumerated"/>
<option id="com.arm.toolchain.v6.base.options.inst.197022885" name="Instruction set" superClass="com.arm.toolchain.v6.base.options.inst" useByScannerDiscovery="false" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
<targetPlatform id="com.arm.eclipse.build.config.v6.exe.debug.779721393..127053145" name=""/>
<builder buildPath="${workspace_loc:/sample_threadx}/Debug" id="com.arm.toolchain.v6.builder.1758911861" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.arm.toolchain.v6.builder"/>
<tool id="com.arm.tool.c.compiler.v6.418132421" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.min" id="com.arm.tool.c.compiler.v6.base.option.optlevel.19928102" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.tool.c.compiler.v6.base.options.debug.level.337331949" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" valueType="enumerated"/>
<option id="com.arm.tool.c.compiler.v6.base.option.cpu.58215761" name="CPU (-mcpu)" superClass="com.arm.tool.c.compiler.v6.base.option.cpu" useByScannerDiscovery="true" value="cortex-r4f" valueType="string"/>
<option id="com.arm.tool.c.compiler.v6.base.option.target.1459440744" 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.fpu.1654602745" name="FPU (-mfpu)" superClass="com.arm.tool.c.compiler.v6.base.option.fpu" useByScannerDiscovery="true" value="vfpv3-d16" valueType="string"/>
<option id="com.arm.tool.c.compiler.v6.base.option.floatabi.1877168310" 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.hard" valueType="enumerated"/>
<option id="com.arm.tool.c.compiler.v6.base.option.inst.1182112443" 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 id="com.arm.tool.c.compiler.v6.base.option.incpath.758740586" name="Include path (-I)" superClass="com.arm.tool.c.compiler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/tx/inc_port}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/tx/inc_generic}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/tx/inc_generic_modules}&quot;"/>
</option>
<option id="com.arm.tool.c.compiler.v6.base.option.defmac.1457716013" name="Define macro (-D)" superClass="com.arm.tool.c.compiler.v6.base.option.defmac" useByScannerDiscovery="false"/>
<inputType id="com.arm.tool.c.compiler.v6.base.input.166957004" superClass="com.arm.tool.c.compiler.v6.base.input"/>
<inputType id="com.arm.tool.cpp.compiler.v6.base.input.514187035" superClass="com.arm.tool.cpp.compiler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.cpp.compiler.v6.1802813297" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.min" id="com.arm.tool.c.compiler.v6.base.option.optlevel.1205322853" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.tool.c.compiler.v6.base.options.debug.level.1437798868" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" valueType="enumerated"/>
</tool>
<tool id="com.arm.tool.assembler.v6.1811190142" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6">
<option defaultValue="com.arm.tool.assembler.v6.base.options.debug.level.std" id="com.arm.tool.assembler.v6.base.options.debug.level.566763408" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" useByScannerDiscovery="false" valueType="enumerated"/>
<option id="com.arm.tool.assembler.v6.base.option.cpu.1716622463" name="CPU (-mcpu)" superClass="com.arm.tool.assembler.v6.base.option.cpu" useByScannerDiscovery="false" value="cortex-r4f" valueType="string"/>
<option id="com.arm.tool.assembler.v6.base.option.target.776341361" 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.fpu.1794164835" name="FPU (-mfpu)" superClass="com.arm.tool.assembler.v6.base.option.fpu" useByScannerDiscovery="true" value="vfpv3-d16" valueType="string"/>
<option id="com.arm.tool.assembler.v6.base.option.floatabi.1726500202" 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.hard" valueType="enumerated"/>
<option id="com.arm.tool.assembler.v6.base.option.inst.147805472" 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.option.defmac.2087651802" name="Define macro (-D)" superClass="com.arm.tool.assembler.v6.base.option.defmac" useByScannerDiscovery="false"/>
<inputType id="com.arm.tool.assembler.v6.base.input.2040825079" superClass="com.arm.tool.assembler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.c.linker.v6.1953954901" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6">
<option id="com.arm.tool.c.linker.option.scatter.1560645973" name="Scatter file (--scatter)" superClass="com.arm.tool.c.linker.option.scatter" useByScannerDiscovery="false" value="../sample_threadx.scat" valueType="string"/>
<option id="com.arm.tool.c.linker.option.entry.954936793" 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.libs.1433839093" name="User library files" superClass="com.arm.tool.c.linker.libs" useByScannerDiscovery="false" valueType="libs">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/tx/Debug/tx.a}&quot;"/>
</option>
<option id="com.arm.tool.c.linker.option.sizes.1385096859" name="List code and data sizes of output image (--info=sizes)" superClass="com.arm.tool.c.linker.option.sizes" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="com.arm.tool.c.linker.option.imagemap.98974534" name="Generate image map (--map)" superClass="com.arm.tool.c.linker.option.imagemap" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="com.arm.tool.c.linker.option.redirectoutput.1754253893" name="Redirect diagnostics output to file (--list)" superClass="com.arm.tool.c.linker.option.redirectoutput" useByScannerDiscovery="false" value="map.map" valueType="string"/>
</tool>
<tool id="com.arm.tool.librarian.v6.675978717" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry 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.713968185">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.exe.release.713968185" 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.713968185" name="Release" parent="com.arm.eclipse.build.config.v6.exe.release">
<folderInfo id="com.arm.eclipse.build.config.v6.exe.release.713968185." name="/" resourcePath="">
<toolChain id="com.arm.toolchain.v6.exe.release.1460511458" name="Arm Compiler 6 (DS-5 built-in)" superClass="com.arm.toolchain.v6.exe.release">
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.toolchain.v6.base.options.debug.level.2051889961" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" valueType="enumerated"/>
<targetPlatform id="com.arm.eclipse.build.config.v6.exe.release.713968185..616485282" name=""/>
<builder buildPath="${workspace_loc:/sample_threadx}/Release" id="com.arm.toolchain.v6.builder.870395099" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.arm.toolchain.v6.builder"/>
<tool id="com.arm.tool.c.compiler.v6.259065810" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.high" id="com.arm.tool.c.compiler.v6.base.option.optlevel.1016945654" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.tool.c.compiler.v6.base.options.debug.level.1192425502" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" valueType="enumerated"/>
<inputType id="com.arm.tool.c.compiler.v6.base.input.1880078422" superClass="com.arm.tool.c.compiler.v6.base.input"/>
<inputType id="com.arm.tool.cpp.compiler.v6.base.input.1562364562" superClass="com.arm.tool.cpp.compiler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.cpp.compiler.v6.162044254" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.high" id="com.arm.tool.c.compiler.v6.base.option.optlevel.1518199483" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.tool.c.compiler.v6.base.options.debug.level.1403473824" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" valueType="enumerated"/>
</tool>
<tool id="com.arm.tool.assembler.v6.2117272930" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6">
<option defaultValue="com.arm.tool.assembler.v6.base.options.debug.level.none" id="com.arm.tool.assembler.v6.base.options.debug.level.1879820366" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" valueType="enumerated"/>
<inputType id="com.arm.tool.assembler.v6.base.input.1863547577" superClass="com.arm.tool.assembler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.c.linker.v6.1898632817" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6"/>
<tool id="com.arm.tool.librarian.v6.74576969" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6"/>
</toolChain>
</folderInfo>
</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.1139105725" name="Executable" projectType="com.arm.eclipse.build.project.v6.exe"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="com.arm.projectSettings" version="5.25"/>
<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>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
</cproject>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>sample_threadx_module_manager</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>
</projectDescription>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="com.arm.eclipse.build.config.v6.exe.debug.779721393" 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="1257603729813011790" 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 &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
<configuration id="com.arm.eclipse.build.config.v6.exe.release.713968185" 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="1208898303067000398" 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 &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>

View File

@@ -0,0 +1,239 @@
/** GIC start **/
/* ------------------------- Interrupt Number Definition ------------------------ */
#include "gic.h"
#define VE_R4_GIC_DISTRIBUTOR_BASE (0xAE001000UL) /*!< (PL390 GIC Distributor ) Base Address */
#define VE_R4_GIC_INTERFACE_BASE (0xAE000000UL) /*!< (PL390 GIC CPU Interface) Base Address */
#define GICDistributor ((GICDistributor_Type *) VE_R4_GIC_DISTRIBUTOR_BASE ) /*!< GIC Distributor configuration struct */
#define GICInterface ((GICInterface_Type *) VE_R4_GIC_INTERFACE_BASE ) /*!< GIC Interface configuration struct */
/* Globals for use of post-scatterloading code that must access GIC */
const uint32_t GICDistributor_BASE = VE_R4_GIC_DISTRIBUTOR_BASE;
const uint32_t GICInterface_BASE = VE_R4_GIC_INTERFACE_BASE;
#if 0
void GIC_SetICDICFR (const uint32_t *ICDICFRn)
{
uint32_t i, num_irq;
//Get the maximum number of interrupts that the GIC supports
num_irq = 32 * ((GIC_DistributorInfo() & 0x1f) + 1);
for (i = 0; i < (num_irq/16); i++)
{
GICDistributor->ICDISPR[i] = *ICDICFRn++;
}
}
uint32_t GIC_DistributorImplementer(void)
{
return (uint32_t)(GICDistributor->ICDIIDR);
}
uint32_t GIC_GetTarget(IRQn_Type IRQn)
{
char* field = (char*)&(GICDistributor->ICDIPTR[IRQn / 4]);
field += IRQn % 4;
return ((uint32_t)*field & 0xf);
}
IRQn_Type GIC_AcknowledgePending(void)
{
return (IRQn_Type)(GICInterface->ICCIAR);
}
uint32_t GIC_GetBinaryPoint(uint32_t binary_point)
{
return (uint32_t)GICInterface->ICCBPR;
}
uint32_t GIC_GetIRQStatus(IRQn_Type IRQn)
{
uint32_t pending, active;
active = ((GICDistributor->ICDABR[IRQn / 32]) >> (IRQn % 32)) & 0x1;
pending =((GICDistributor->ICDISPR[IRQn / 32]) >> (IRQn % 32)) & 0x1;
return ((active<<1) | pending);
}
void GIC_SendSGI(IRQn_Type IRQn, uint32_t target_list, uint32_t filter_list)
{
GICDistributor->ICDSGIR = ((filter_list & 0x3) << 24) | ((target_list & 0xff) << 16) | (IRQn & 0xf);
}
void GIC_EndInterrupt(IRQn_Type IRQn)
{
GICInterface->ICCEOIR = IRQn;
}
void GIC_SetPendingIRQ(IRQn_Type IRQn)
{
GICDistributor->ICDISPR[IRQn / 32] = 1 << (IRQn % 32);
}
void GIC_ClearPendingIRQ(IRQn_Type IRQn)
{
GICDistributor->ICDICPR[IRQn / 32] = 1 << (IRQn % 32);
}
#endif
void GIC_EnableDistributor(void)
{
GICDistributor->ICDDCR |= 1; //enable distributor
}
void GIC_DisableDistributor(void)
{
GICDistributor->ICDDCR &=~1; //disable distributor
}
void GIC_SetTarget(IRQn_Type IRQn, uint32_t cpu_target)
{
char* field = (char*)&(GICDistributor->ICDIPTR[IRQn / 4]);
field += IRQn % 4;
*field = (char)cpu_target & 0xf;
}
void GIC_EnableInterface(void)
{
GICInterface->ICCICR |= 1; //enable interface
}
void GIC_DisableInterface(void)
{
GICInterface->ICCICR &=~1; //disable distributor
}
void GIC_EnableIRQ(IRQn_Type IRQn)
{
GICDistributor->ICDISER[IRQn / 32] = 1 << (IRQn % 32);
}
void GIC_DisableIRQ(IRQn_Type IRQn)
{
GICDistributor->ICDICER[IRQn / 32] = 1 << (IRQn % 32);
}
uint32_t GIC_DistributorInfo(void)
{
return (uint32_t)(GICDistributor->ICDICTR);
}
void GIC_SetLevelModel(IRQn_Type IRQn, int8_t edge_level, int8_t model)
{ // Word-size read/writes must be used to access this register
volatile uint32_t * field = &(GICDistributor->ICDICFR[IRQn / 16]);
unsigned bit_shift = (IRQn % 16)<<1;
unsigned int save_word;
save_word = *field;
save_word &= (~(3 << bit_shift));
*field = (save_word | (((edge_level<<1) | model) << bit_shift));
}
void GIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
char* field = (char*)&(GICDistributor->ICDIPR[IRQn / 4]);
field += IRQn % 4;
*field = (char)priority;
}
uint32_t GIC_GetPriority(IRQn_Type IRQn)
{
char* field = (char*)&(GICDistributor->ICDIPR[IRQn / 4]);
field += IRQn % 4;
return (uint32_t)*field;
}
void GIC_InterfacePriorityMask(uint32_t priority)
{
GICInterface->ICCPMR = priority & 0xff; //set priority mask
}
void GIC_SetBinaryPoint(uint32_t binary_point)
{
GICInterface->ICCBPR = binary_point & 0x07; //set binary point
}
void GIC_DistInit(void)
{
IRQn_Type i;
uint32_t num_irq = 0;
uint32_t priority_field;
//A reset sets all bits in the ICDISRs corresponding to the SPIs to 0,
//configuring all of the interrupts as Secure.
//Disable interrupt forwarding
GIC_DisableDistributor();
//Get the maximum number of interrupts that the GIC supports
num_irq = 32 * ((GIC_DistributorInfo() & 0x1f) + 1);
/* Priority level is implementation defined.
To determine the number of priority bits implemented write 0xFF to an ICDIPR
priority field and read back the value stored.*/
GIC_SetPriority((IRQn_Type)0, 0xff);
priority_field = GIC_GetPriority((IRQn_Type)0);
for (i = (IRQn_Type)32; i < num_irq; i++)
{
//Disable the SPI interrupt
GIC_DisableIRQ(i);
//Set level-sensitive and 1-N model
GIC_SetLevelModel(i, 0, 1);
//Set priority
GIC_SetPriority(i, priority_field/2);
//Set target list to CPU0
GIC_SetTarget(i, 1);
}
//Enable distributor
GIC_EnableDistributor();
}
void GIC_CPUInterfaceInit(void)
{
IRQn_Type i;
uint32_t priority_field;
//A reset sets all bits in the ICDISRs corresponding to the SPIs to 0,
//configuring all of the interrupts as Secure.
//Disable interrupt forwarding
GIC_DisableInterface();
/* Priority level is implementation defined.
To determine the number of priority bits implemented write 0xFF to an ICDIPR
priority field and read back the value stored.*/
GIC_SetPriority((IRQn_Type)0, 0xff);
priority_field = GIC_GetPriority((IRQn_Type)0);
//SGI and PPI
for (i = (IRQn_Type)0; i < 32; i++)
{
//Set level-sensitive and 1-N model for PPI
if(i > 15)
GIC_SetLevelModel(i, 0, 1);
//Disable SGI and PPI interrupts
GIC_DisableIRQ(i);
//Set priority
GIC_SetPriority(i, priority_field/2);
}
//Enable interface
GIC_EnableInterface();
//Set binary point to 0
GIC_SetBinaryPoint(0);
//Set priority mask
GIC_InterfacePriorityMask(0xff);
}
void GIC_Enable(void)
{
GIC_DistInit();
GIC_CPUInterfaceInit(); //per CPU
}
/** GIC end **/

View File

@@ -0,0 +1,360 @@
/**************************************************************************//**
* @file gic.h
* @brief Generic Interrupt Controller (GIC) functions
* @version
* @date 29 August 2013
*
* @note
*
******************************************************************************/
/* Copyright (c) 2011 - 2013 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#ifndef GIC_H_
#define GIC_H_
#include "stdint.h"
typedef enum IRQn
{
/****** SGI Interrupts Numbers ****************************************/
SGI0_IRQn = 0,
SGI1_IRQn = 1,
SGI2_IRQn = 2,
SGI3_IRQn = 3,
SGI4_IRQn = 4,
SGI5_IRQn = 5,
SGI6_IRQn = 6,
SGI7_IRQn = 7,
SGI8_IRQn = 8,
SGI9_IRQn = 9,
SGI10_IRQn = 10,
SGI11_IRQn = 11,
SGI12_IRQn = 12,
SGI13_IRQn = 13,
SGI14_IRQn = 14,
SGI15_IRQn = 15,
/****** Cortex-R4 Processor Exceptions Numbers ****************************************/
PrivTimer_IRQn = 34, /*!< Private Timer Interrupt */
/****** Platform Exceptions Numbers ***************************************************/
Watchdog_IRQn = 32, /*!< SP805 Interrupt */
Timer0_IRQn = 34, /*!< SP804 Interrupt */
Timer1_IRQn = 35, /*!< SP804 Interrupt */
RTClock_IRQn = 36, /*!< PL031 Interrupt */
UART0_IRQn = 37, /*!< PL011 Interrupt */
UART1_IRQn = 38, /*!< PL011 Interrupt */
UART2_IRQn = 39, /*!< PL011 Interrupt */
UART3_IRQn = 40, /*!< PL011 Interrupt */
MCI0_IRQn = 41, /*!< PL180 Interrupt (1st) */
MCI1_IRQn = 42, /*!< PL180 Interrupt (2nd) */
AACI_IRQn = 43, /*!< PL041 Interrupt */
Keyboard_IRQn = 44, /*!< PL050 Interrupt */
Mouse_IRQn = 45, /*!< PL050 Interrupt */
CLCD_IRQn = 46, /*!< PL111 Interrupt */
Ethernet_IRQn = 47, /*!< SMSC_91C111 Interrupt */
VFS2_IRQn = 73, /*!< VFS2 Interrupt */
} IRQn_Type;
/* IO definitions (access restrictions to peripheral registers) */
/**
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/** \brief Structure type to access the Generic Interrupt Controller Distributor (GICD)
*/
typedef struct
{
__IO uint32_t ICDDCR;
__I uint32_t ICDICTR;
__I uint32_t ICDIIDR;
uint32_t RESERVED0[29];
__IO uint32_t ICDISR[32];
__IO uint32_t ICDISER[32];
__IO uint32_t ICDICER[32];
__IO uint32_t ICDISPR[32];
__IO uint32_t ICDICPR[32];
__I uint32_t ICDABR[32];
uint32_t RESERVED1[32];
__IO uint32_t ICDIPR[256];
__IO uint32_t ICDIPTR[256];
__IO uint32_t ICDICFR[64];
uint32_t RESERVED2[128];
__IO uint32_t ICDSGIR;
} GICDistributor_Type;
/** \brief Structure type to access the Controller Interface (GICC)
*/
typedef struct
{
__IO uint32_t ICCICR; // +0x000 - RW - CPU Interface Control Register
__IO uint32_t ICCPMR; // +0x004 - RW - Interrupt Priority Mask Register
__IO uint32_t ICCBPR; // +0x008 - RW - Binary Point Register
__I uint32_t ICCIAR; // +0x00C - RO - Interrupt Acknowledge Register
__IO uint32_t ICCEOIR; // +0x010 - WO - End of Interrupt Register
__I uint32_t ICCRPR; // +0x014 - RO - Running Priority Register
__I uint32_t ICCHPIR; // +0x018 - RO - Highest Pending Interrupt Register
__IO uint32_t ICCABPR; // +0x01C - RW - Aliased Binary Point Register
uint32_t RESERVED[55];
__I uint32_t ICCIIDR; // +0x0FC - RO - CPU Interface Identification Register
} GICInterface_Type;
/*@} end of GICD */
/* ########################## GIC functions #################################### */
/** \brief Functions that manage interrupts via the GIC.
@{
*/
/** \brief Enable DistributorGICInterface->ICCICR |= 1; //enable interface
Enables the forwarding of pending interrupts to the CPU interfaces.
*/
void GIC_EnableDistributor(void);
/** \brief Disable Distributor
Disables the forwarding of pending interrupts to the CPU interfaces.
*/
void GIC_DisableDistributor(void);
/** \brief Provides information about the configuration of the GIC.
Provides information about the configuration of the GIC.
- whether the GIC implements the Security Extensions
- the maximum number of interrupt IDs that the GIC supports
- the number of CPU interfaces implemented
- if the GIC implements the Security Extensions, the maximum number of implemented Lockable Shared Peripheral Interrupts (LSPIs).
\return Distributor Information.
*/
uint32_t GIC_DistributorInfo(void);
/** \brief Distributor Implementer Identification Register.
Distributor Implementer Identification Register
\return Implementer Information.
*/
uint32_t GIC_DistributorImplementer(void);
/** \brief Set list of processors that the interrupt is sent to if it is asserted.
The ICDIPTRs provide an 8-bit CPU targets field for each interrupt supported by the GIC.
This field stores the list of processors that the interrupt is sent to if it is asserted.
\param [in] IRQn Interrupt number.
\param [in] target CPU target
*/
void GIC_SetTarget(IRQn_Type IRQn, uint32_t cpu_target);
/** \brief Get list of processors that the interrupt is sent to if it is asserted.
The ICDIPTRs provide an 8-bit CPU targets field for each interrupt supported by the GIC.
This field stores the list of processors that the interrupt is sent to if it is asserted.
\param [in] IRQn Interrupt number.
\param [in] target CPU target
*/
uint32_t GIC_GetTarget(IRQn_Type IRQn);
/** \brief Enable Interface
Enables the signalling of interrupts to the target processors.
*/
void GIC_EnableInterface(void);
/** \brief Disable Interface
Disables the signalling of interrupts to the target processors.
*/
void GIC_DisableInterface(void);
/** \brief Acknowledge Interrupt
The function acknowledges the highest priority pending interrupt and returns its IRQ number.
\return Interrupt number
*/
IRQn_Type GIC_AcknowledgePending(void);
/** \brief End Interrupt
The function writes the end of interrupt register, indicating that handling of the interrupt is complete.
\param [in] IRQn Interrupt number.
*/
void GIC_EndInterrupt(IRQn_Type IRQn);
/** \brief Enable Interrupt
Set-enable bit for each interrupt supported by the GIC.
\param [in] IRQn External interrupt number.
*/
void GIC_EnableIRQ(IRQn_Type IRQn);
/** \brief Disable Interrupt
Clear-enable bit for each interrupt supported by the GIC.
\param [in] IRQn Number of the external interrupt to disable
*/
void GIC_DisableIRQ(IRQn_Type IRQn);
/** \brief Set Pending Interrupt
Set-pending bit for each interrupt supported by the GIC.
\param [in] IRQn Interrupt number.
*/
void GIC_SetPendingIRQ(IRQn_Type IRQn);
/** \brief Clear Pending Interrupt
Clear-pending bit for each interrupt supported by the GIC
\param [in] IRQn Number of the interrupt for clear pending
*/
void GIC_ClearPendingIRQ(IRQn_Type IRQn);
/** \brief Int_config field for each interrupt supported by the GIC.
This field identifies whether the corresponding interrupt is:
(1) edge-triggered or (0) level-sensitive
(1) 1-N model or (0) N-N model
\param [in] IRQn Interrupt number.
\param [in] edge_level (1) edge-triggered or (0) level-sensitive
\param [in] model (1) 1-N model or (0) N-N model
*/
void GIC_SetLevelModel(IRQn_Type IRQn, int8_t edge_level, int8_t model);
/** \brief Set Interrupt Priority
The function sets the priority of an interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
void GIC_SetPriority(IRQn_Type IRQn, uint32_t priority);
/** \brief Get Interrupt Priority
The function reads the priority of an interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority.
*/
uint32_t GIC_GetPriority(IRQn_Type IRQn);
/** \brief CPU Interface Priority Mask Register
The priority mask level for the CPU interface. If the priority of an interrupt is higher than the
value indicated by this field, the interface signals the interrupt to the processor.
\param [in] Mask.
*/
void GIC_InterfacePriorityMask(uint32_t priority);
/** \brief Set the binary point.
Set the point at which the priority value fields split into two parts, the group priority field and the subpriority field.
\param [in] Mask.
*/
void GIC_SetBinaryPoint(uint32_t binary_point);
/** \brief Get the binary point.
Get the point at which the priority value fields split into two parts, the group priority field and the subpriority field.
\return Binary point.
*/
uint32_t GIC_GetBinaryPoint(uint32_t binary_point);
/** \brief Get Interrupt state.
Get the interrupt state, whether pending and/or active
\return 0 - inactive, 1 - pending, 2 - active, 3 - pending and active
*/
uint32_t GIC_GetIRQStatus(IRQn_Type IRQn);
/** \brief Send Software Generated interrupt
Provides an interrupt priority filter. Only interrupts with higher priority than the value in this register can be signalled to the processor.
GIC_InterfacePriorityMask
\param [in] IRQn The Interrupt ID of the SGI.
\param [in] target_list CPUTargetList
\param [in] filter_list TargetListFilter
*/
void GIC_SendSGI(IRQn_Type IRQn, uint32_t target_list, uint32_t filter_list);
/** \brief API call to initialise the interrupt distributor
API call to initialise the interrupt distributor
*/
void GIC_DistInit(void);
/** \brief API call to initialise the CPU interface
API call to initialise the CPU interface
*/
void GIC_CPUInterfaceInit(void);
/** \brief API call to set the Interrupt Configuration Registers
API call to initialise the Interrupt Configuration Registers
*/
void GIC_SetICDICFR (const uint32_t *ICDICFRn);
/** \brief API call to Enable the GIC
API call to Enable the GIC
*/
void GIC_Enable(void);
#endif /* GIC_H_ */

View File

@@ -0,0 +1,39 @@
;**************************************************
; Copyright (c) 2017 ARM Ltd. All rights reserved.
;**************************************************
; Scatter-file for RTX Example on Versatile Express R4
; This scatter-file places application code, data and peripherals at suitable addresses in the memory map.
; This platform has 2GB SDRAM starting at 0x0.
SDRAM 0x0 0x40000000
{
CODE +0 0x200000
{
startup.o (Vectors, +FIRST) ; Vector table and other (assembler) startup code
* (InRoot$$Sections) ; All (library) code that must be in a root region
* (+RO-CODE) ; Application RO code (.text)
* (+RO-DATA) ; Application RO data (.constdata)
}
IRQ_STACK +0 ALIGN 8 EMPTY 1024 {}
FIQ_STACK +0 ALIGN 8 EMPTY 512 {}
SVC_STACK +0 ALIGN 8 EMPTY 2048 {}
SYS_STACK +0 ALIGN 8 EMPTY 2048 {}
ABORT_STACK +0 ALIGN 8 EMPTY 2048 {}
; Application RW & ZI data (.data & .bss)
DATA +0 0x100000
{
* (+RW,+ZI)
}
PERIPHERALS 0xA0000000 EMPTY 0x20000000 { }; Peripherals
}

View File

@@ -0,0 +1,119 @@
/* Small demonstration of the ThreadX module manager. */
#include "tx_api.h"
#include "txm_module.h"
#include "timer.h"
#define DEMO_STACK_SIZE 1024
/* Define the ThreadX object control blocks... */
TX_THREAD module_manager;
TXM_MODULE_INSTANCE my_module;
UCHAR manager_stack[1024];
/* Define the object pool area. */
UCHAR object_memory[16384];
/* Define the module data pool area. */
#define MODULE_DATA_SIZE 65536
unsigned char module_data_area[MODULE_DATA_SIZE];
/* Module code is in an array created by module_to_c_array utility. */
extern const unsigned char module_code[];
/* Define the count of memory faults. */
ULONG memory_faults;
/* Define thread prototypes. */
void module_manager_entry(ULONG thread_input);
/* Define fault handler. */
VOID module_fault_handler(TX_THREAD *thread, TXM_MODULE_INSTANCE *module)
{
/* Just increment the fault counter. */
memory_faults++;
}
/* Define main entry point. */
int main()
{
/* Setup the timer. */
timer_init();
/* Enter the ThreadX kernel. */
tx_kernel_enter();
}
/* Define what the initial system looks like. */
void tx_application_define(void *first_unused_memory)
{
tx_thread_create(&module_manager, "Module Manager Thread", module_manager_entry, 0,
manager_stack, DEMO_STACK_SIZE,
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
}
/* Define the test threads. */
void module_manager_entry(ULONG thread_input)
{
/* Initialize the module manager. */
txm_module_manager_initialize((VOID *) module_data_area, MODULE_DATA_SIZE);
txm_module_manager_object_pool_create(object_memory, sizeof(object_memory));
/* Register a fault handler. */
txm_module_manager_memory_fault_notify(module_fault_handler);
/* Load the module that is already there, in this example it is placed there by the multiple image download. */
txm_module_manager_in_place_load(&my_module, "my module", (VOID *) 0x00100000 /*module_code*/);
/* Enable 128 byte read/write shared memory region at 0x08025000. */
txm_module_manager_external_memory_enable(&my_module, (void *) 0x08025000, 128, TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE);
/* Start the module. */
txm_module_manager_start(&my_module);
/* Sleep for a while.... */
tx_thread_sleep(300);
/* Stop the module. */
txm_module_manager_stop(&my_module);
/* Unload the module. */
txm_module_manager_unload(&my_module);
/* Load the module that is already there. */
txm_module_manager_in_place_load(&my_module, "my module", (VOID *) 0x00100000);
/* Set maximum module priority to 5. */
txm_module_manager_maximum_module_priority_set(&my_module, 5);
/* In this demo, module threads 0 and 5 will not start because their priorities
* are higher than 5. */
/* Start the module again. */
txm_module_manager_start(&my_module);
/* Now just spin... */
while(1)
{
tx_thread_sleep(100);
}
}

View File

@@ -0,0 +1,249 @@
//----------------------------------------------------------------
// Cortex-R4(F) Embedded example - Startup Code
//
// Copyright (c) 2006-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.
//----------------------------------------------------------------
#define FIQ_MODE 0x11
#define IRQ_MODE 0x12
#define SVC_MODE 0x13
#define ABT_MODE 0x17
#define SYS_MODE 0x1F
//----------------------------------------------------------------
.eabi_attribute Tag_ABI_align8_preserved,1
.section VECTORS,"ax"
.align 3
.cfi_sections .debug_frame // put stack frame info into .debug_frame instead of .eh_frame
//----------------------------------------------------------------
// 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.
.global Vectors
Vectors:
LDR PC, Reset_Addr
LDR pc,=__tx_undefined // Undefined handler
LDR pc,=__tx_svc_interrupt // Software interrupt handler
LDR pc,=__tx_prefetch_handler // Prefetch exception handler
LDR pc,=__tx_abort_handler // Abort exception handler
LDR pc,=__tx_reserved_handler // Reserved exception handler
LDR pc,=__tx_irq_handler // IRQ interrupt handler
LDR pc,=__tx_fiq_handler // FIQ interrupt handler
.balign 4
Reset_Addr: .word Reset_Handler
Undefined_Addr: .word __tx_undefined
SVC_Addr: .word __tx_svc_interrupt
Prefetch_Addr: .word __tx_prefetch_handler
Abort_Addr: .word __tx_abort_handler
IRQ_Addr: .word __tx_irq_handler
FIQ_Addr: .word __tx_fiq_handler
//----------------------------------------------------------------
// Reset Handler
//----------------------------------------------------------------
.global Reset_Handler
.type Reset_Handler, "function"
Reset_Handler:
//----------------------------------------------------------------
// Disable MPU and caches
//----------------------------------------------------------------
// Disable MPU and cache in case it was 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 MPU
DSB // Ensure all previous loads/stores have completed
MCR p15, 0, r0, c1, c0, 0 // Write System Control Register
ISB // Ensure subsequent insts execute wrt new MPU settings
//----------------------------------------------------------------
// Disable Branch prediction
//----------------------------------------------------------------
// In the Cortex-R4, the Z-bit of the SCTLR does not control the program flow prediction.
// Some control bits in the ACTLR control the program flow and prefetch features instead.
// These are enabled by default, but are shown here for completeness.
MRC p15, 0, r0, c1, c0, 1 // Read ACTLR
ORR r0, r0, #(0x1 << 17) // Enable RSDIS bit 17 to disable the return stack
ORR r0, r0, #(0x1 << 16) // Clear BP bit 15 and set BP bit 16:
BIC r0, r0, #(0x1 << 15) // Branch always not taken and history table updates disabled
MCR p15, 0, r0, c1, c0, 1 // Write ACTLR
ISB
//----------------------------------------------------------------
// Cache invalidation
//----------------------------------------------------------------
DSB // Complete all outstanding explicit memory operations
MOV r0, #0
MCR p15, 0, r0, c7, c5, 0 // Invalidate entire instruction cache
MCR p15, 0, r0, c15, c5, 0 // Invalidate entire data cache
//----------------------------------------------------------------
// Initialize Supervisor Mode Stack using Linker symbol from scatter file.
// Stacks must be 8 byte aligned.
//----------------------------------------------------------------
/****** NOTE ****** We must be in SVC MODE at this point. Some monitors
enter this routine in USER mode and require a software interrupt to
change into SVC mode. */
#ifdef TX_ENABLE_IRQ_NESTING
/* Setup the system mode stack for nested interrupt support */
MOV r3, #SYS_MODE // Build SYS mode CPSR
MSR CPSR_c, r3 // Enter SYS mode
LDR sp, =Image$$SYS_STACK$$ZI$$Limit // Setup SYS stack pointer
#endif
CPS #ABT_MODE // Build Abort mode CPSR
LDR sp, =Image$$ABORT_STACK$$ZI$$Limit // Setup abort stack pointer
CPS #FIQ_MODE // Build FIQ mode CPSR
LDR sp, =Image$$FIQ_STACK$$ZI$$Limit // Setup FIQ stack pointer
MOV sl, #0 // Clear sl
MOV fp, #0 // Clear fp
CPS #IRQ_MODE // Build IRQ mode CPSR
LDR sp, =Image$$IRQ_STACK$$ZI$$Limit // Setup IRQ stack pointer
CPS #SVC_MODE // Build SVC mode CPSR
LDR sp, =Image$$SVC_STACK$$ZI$$Limit // Setup SVC stack pointer
//----------------------------------------------------------------
// TCM Configuration
//----------------------------------------------------------------
// Cortex-R4 optionally provides two Tightly-Coupled Memory (TCM) blocks (ATCM and BTCM) for fast access to code or data.
// ATCM typically holds interrupt or exception code that must be accessed at high speed,
// without any potential delay resulting from a cache miss.
// BTCM typically holds a block of data for intensive processing, such as audio or video data.
// In the Cortex-R4 processor, both ATCM and BTCM support both instruction and data accesses.
// The following illustrates basic TCM configuration, as the basis for exploration by the user
#ifdef TCM
.global Image$$ATCM$$Base
.global Image$$BTCM0$$Base
.global Image$$BTCM1$$Base
MRC p15, 0, r0, c0, c0, 2 // Read TCM Type Register
// r0 now contains ATCM & BTCM availability
MRC p15, 0, r0, c9, c1, 1 // Read ATCM Region Register
// r0 now contains ATCM size in bits [6:2]
MRC p15, 0, r0, c9, c1, 0 // Read BTCM Region Register
// r0 now contains BTCM size in bits [6:2]
// The Cortex-R4F Core Tile has
// 64K ATCM from 0xE0FD0000 to 0xE0FDFFFF
// 64K BTCM0 from 0xE0FE0000 to 0xE0FEFFFF
// 64K BTCM1 from 0xE0FF0000 to 0xE0FFFFFF
LDR r0, =Image$$ATCM$$Base // Set ATCM base address
ORR r0, r0, #1 // Enable it
MCR p15, 0, r0, c9, c1, 1 // Write ATCM Region Register
LDR r0, =Image$$BTCM0$$Base // Set BTCM base address
ORR r0, r0, #1 // Enable it
MCR p15, 0, r0, c9, c1, 0 // Write BTCM Region Register
#endif
#ifdef __ARM_FP
//----------------------------------------------------------------
// Enable access to 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 hardware
//----------------------------------------------------------------
MOV r0, #0x40000000
VMSR FPEXC, r0 // Write FPEXC register, EN bit set
#endif
//----------------------------------------------------------------
// Enable Branch prediction
//----------------------------------------------------------------
// In the Cortex-R4, the Z-bit of the SCTLR does not control the program flow prediction.
// Some control bits in the ACTLR control the program flow and prefetch features instead.
// These are enabled by default, but are shown here for completeness.
MRC p15, 0, r0, c1, c0, 1 // Read ACTLR
BIC r0, r0, #(0x1 << 17) // Clear RSDIS bit 17 to enable return stack
BIC r0, r0, #(0x1 << 16) // Clear BP bit 15 and BP bit 16:
BIC r0, r0, #(0x1 << 15) // Normal operation, BP is taken from the global history table.
MCR p15, 0, r0, c1, c0, 1 // Write ACTLR
ISB
/* Enable the GIC. */
BL GIC_Enable
.global __main
B __main
.size Reset_Handler, . - Reset_Handler
//----------------------------------------------------------------
// Global Enable for Instruction and Data Caching
//----------------------------------------------------------------
.global enable_caches
.type enable_caches, "function"
.cfi_startproc
enable_caches:
MRC p15, 0, r0, c1, c0, 0 // Read System Control Register
ORR r0, r0, #(0x1 << 12) // enable I Cache
ORR r0, r0, #(0x1 << 2) // enable D Cache
MCR p15, 0, r0, c1, c0, 0 // Write System Control Register
ISB
BX lr
.cfi_endproc
.size enable_caches, . - enable_caches
/* Define initial heap/stack routine for the ARM RealView (and ADS) startup code. This
routine will set the initial stack to use the ThreadX IRQ & FIQ &
(optionally SYS) stack areas. */
.global __user_initial_stackheap
.type __user_initial_stackheap, %function
__user_initial_stackheap:
LDR r1, =Image$$SVC_STACK$$ZI$$Limit
BX lr // Return to caller

View File

@@ -0,0 +1,28 @@
#include "gic.h"
/* Systick registers */
#define PRIVTIM_IRQ 34
#define PRIVATE_TIMER_BASE (0xB0110000)
#define PRIVTIM_RELOAD (*((volatile uint32_t *)(PRIVATE_TIMER_BASE + 0x0)))
#define PRIVTIM_CURRENT (*((volatile uint32_t *)(PRIVATE_TIMER_BASE + 0x4)))
#define PRIVTIM_CTRL (*((volatile uint32_t *)(PRIVATE_TIMER_BASE + 0x8)))
#define PRIVTIM_STATUS (*((volatile uint32_t *)(PRIVATE_TIMER_BASE + 0xc)))
#define OS_CLOCK 12000000
#define OS_TICK 1000
#define OS_TRV ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1)
#define U32 uint32_t
#define GICD_ICDICER0 (*((volatile U32 *)(GICDistributor_BASE + 0x180))) /* - RW - Interrupt Clear-Enable Registers */
#define GICD_ICDISER0 (*((volatile U32 *)(GICDistributor_BASE + 0x100))) /* - RW - Interrupt Set-Enable Registers */
#define GICD_ICDIPR0 (*((volatile U32 *)(GICDistributor_BASE + 0x400))) /* - RW - Interrupt Priority Registers */
#define GICD_ICDSGIR (*((volatile U32 *)(GICDistributor_BASE + 0xf00))) /* - RW - Interrupt Software Interrupt Register */
#define GICD_ICDICERx(irq) *(volatile U32 *)(&GICD_ICDICER0 + irq/32)
#define GICD_ICDISERx(irq) *(volatile U32 *)(&GICD_ICDISER0 + irq/32)
void timer_init()
{
GIC_EnableIRQ(34);
PRIVTIM_RELOAD = 0x200;
PRIVTIM_CTRL |= 0xC0; /* Enable timer, periodic mode */
}

View File

@@ -0,0 +1,4 @@
#ifndef TIMER_H
#define TIMER_H
void timer_init();
#endif

View File

@@ -0,0 +1,477 @@
/**************************************************************************/
/* */
/* 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"
*/
#define THUMB_MASK 0x20 // Thumb bit (5) of CPSR/SPSR
#define ABT_MODE 0x17 // ABT mode
#define SYS_MODE 0x1F // SYS mode
#define GICI_BASE 0xAE000000
#define ICCIAR_OFFSET 0x0000000C
#define ICCEOIR_OFFSET 0x00000010
.global _tx_thread_system_stack_ptr
.global _tx_initialize_unused_memory
.global _tx_thread_context_save
.global _tx_thread_context_restore
#ifdef TX_ENABLE_FIQ_SUPPORT
.global _tx_thread_fiq_context_save
.global _tx_thread_fiq_context_restore
#endif
#ifdef TX_ENABLE_IRQ_NESTING
.global _tx_thread_irq_nesting_start
.global _tx_thread_irq_nesting_end
#endif
#ifdef TX_ENABLE_FIQ_NESTING
.global _tx_thread_fiq_nesting_start
.global _tx_thread_fiq_nesting_end
#endif
.global _tx_timer_interrupt
.global __main
.global _tx_version_id
.global _tx_build_options
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_initialize_low_level Cortex-R4/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, 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 */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_initialize_low_level(VOID)
{ */
.global _tx_initialize_low_level
.type _tx_initialize_low_level, "function"
_tx_initialize_low_level:
/* Save the system stack pointer. */
/* _tx_thread_system_stack_ptr = (VOID_PTR) (sp); */
LDR r0, =Image$$SVC_STACK$$ZI$$Limit
LDR r1, =_tx_thread_system_stack_ptr // Pickup address of system stack ptr
STR r0, [r1] // Pickup system stack
/* Save the first available memory address. */
/* _tx_initialize_unused_memory = (VOID_PTR) Image$$ZI$$Limit + HEAP + [SYS_STACK] + FIQ_STACK + IRQ_STACK; */
LDR r0, =Image$$DATA$$ZI$$Limit
LDR r2, =_tx_initialize_unused_memory // Pickup unused memory ptr address
STR r0, [r2, #0] // Save first free memory address
/* Return to caller. */
BX lr // Return to caller
/* } */
/* Define shells for each of the interrupt vectors. */
.global __tx_undefined
.type __tx_undefined, "function"
__tx_undefined:
B __tx_undefined // Undefined handler
/*** Prefetch and abort handlers are used below for MPU fault handling
.global __tx_prefetch_handler
.type __tx_prefetch_handler, "function"
__tx_prefetch_handler:
B __tx_prefetch_handler // Prefetch exception handler
.global __tx_abort_handler
.type __tx_abort_handler, "function"
__tx_abort_handler:
B __tx_abort_handler // Abort exception handler
*/
.global __tx_reserved_handler
.type __tx_reserved_handler, "function"
__tx_reserved_handler:
B __tx_reserved_handler // Reserved exception handler
.global __tx_irq_handler
.type __tx_irq_handler, "function"
.global __tx_irq_processing_return
.type __tx_irq_processing_return, "function"
__tx_irq_handler:
/* Jump to context save to save system context. */
B _tx_thread_context_save
__tx_irq_processing_return:
/* Acknowledge the interrupt. */
LDR r1, =GICI_BASE // Load the base of the GIC
LDR r0, [r1, #ICCIAR_OFFSET] // Read ICCIAR (GIC CPU Interface register)
DSB // Ensure that interrupt acknowledge completes before re-enabling interrupts
PUSH {r0, r1} // Save the IRQ ID and the GIC base address on the stack
/* Clear the timer interrupt. */
LDR r0, =0xB0110000 // Load the base address of the timer
MOV r1, #1 // Setup value to write to the interrupt clear register - can be anything.
STR r1, [r0, #0x0C] // Clear the interrupt. 0x0C is the offset to the interrupt clear register.
/* 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. */
BL _tx_timer_interrupt // Timer interrupt handler
_tx_not_timer_interrupt:
/* 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
POP {r0, r1} // Restore the IRQ ID and GIC base address
STR r0, [r1, #ICCEOIR_OFFSET] // Write the IRQ ID to the End Of Interrupt register to clear the active bit
/* 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
.type __tx_example_vectored_irq_handler, "function"
__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
.type __tx_fiq_handler, "function"
__tx_fiq_handler:
/* Jump to fiq context save to save system context. */
B _tx_thread_fiq_context_save
.global __tx_fiq_processing_return
.type __tx_fiq_processing_return, "function"
__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
.type __tx_fiq_handler, "function"
__tx_fiq_handler:
B __tx_fiq_handler // FIQ interrupt handler
#endif
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* __tx_prefetch_handler & __tx_abort_handler Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles MPU exceptions and fills the */
/* _txm_module_manager_memory_fault_info struct. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _txm_module_manager_memory_fault_handler */
/* _tx_execution_thread_exit */
/* _tx_thread_schedule */
/* */
/* CALLED BY */
/* */
/* MMU exceptions */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
/********************************************************************
MMU Exception Handling
********************************************************************/
.global _tx_thread_system_state
.global _txm_module_manager_memory_fault_info
.global _tx_thread_current_ptr
.global _txm_module_manager_memory_fault_handler
.global _tx_thread_schedule
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_thread_exit
#endif
.arm /* Exception handler in ARM mode. */
.align 3
.global __tx_prefetch_handler
.global __tx_abort_handler
.type __tx_prefetch_handler, "function"
.type __tx_abort_handler, "function"
__tx_prefetch_handler:
__tx_abort_handler:
STMDB sp!, {r0-r3} // Save some working registers
LDR r3, =_tx_thread_system_state // Pickup address of system state var
LDR r2, [r3, #0] // Pickup system state
ADD r2, r2, #1 // Increment the interrupt counter
STR r2, [r3, #0] // Store it back in the variable
// Now pickup and store all the fault related information
// Pickup the memory fault info struct
LDR r3, =_txm_module_manager_memory_fault_info
LDR r0, =_tx_thread_current_ptr // Build current thread pointer address
LDR r1, [r0] // Pickup the current thread pointer
STR r1, [r3, #0] // Save current thread pointer
MRC p15, 0, r0, c6, c0, 0 // Read DFAR
STR r0, [r3, #8] // Save DFAR
CMP r0, #0 // Was it a data or instruction fault?
SUBEQ lr, lr, #4 // Adjust point of exception for instruction
SUBNE lr, lr, #8 // Adjust point of exception for data
STR lr, [r3, #4] // Save point of fault
MRC p15, 0, r0, c5, c0, 0 // Read DFSR
STR r0, [r3, #12] // Save DFSR
MRC p15, 0, r0, c6, c0, 2 // Read IFAR
STR r0, [r3, #16] // Save IFAR
MRC p15, 0, r0, c5, c0, 1 // Read IFSR
STR r0, [r3, #20] // Save IFSR
MOV r0, #0 // Build zero register
MCR p15, 0, r0, c6, c0, 0 // Clear DFAR
MCR p15, 0, r0, c5, c0, 0 // Clear DFSR
MCR p15, 0, r0, c6, c0, 2 // Clear IFAR
MCR p15, 0, r0, c5, c0, 1 // Clear IFSR
// Save registers r0-r12
POP {r0-r2}
STR r0, [r3, #28] // Save r0
STR r1, [r3, #32] // Save r1
STR r2, [r3, #36] // Save r2
POP {r0}
STR r0, [r3, #40] // Save r3
STR r4, [r3, #44] // Save r4
STR r5, [r3, #48] // Save r5
STR r6, [r3, #52] // Save r6
STR r7, [r3, #56] // Save r7
STR r8, [r3, #60] // Save r8
STR r9, [r3, #64] // Save r9
STR r10,[r3, #68] // Save r10
STR r11,[r3, #72] // Save r11
STR r12,[r3, #76] // Save r12
CPS #SYS_MODE // Enter SYS mode
MOV r0, lr // Pickup lr
MOV r1, sp // Pickup sp
CPS #ABT_MODE // Back to ABT mode
STR r0, [r3, #80] // Save lr
STR r1, [r3, #24] // Save sp
MRS r0, SPSR // Pickup SPSR
STR r0, [r3, #84] // Save SPSR
ORR r0, r0, #SYS_MODE // Return into SYS mode
BIC r0, r0, #THUMB_MASK // Clear THUMB mode
MSR SPSR_c, r0 // Save SPSR
// Call memory manager fault handler
BL _txm_module_manager_memory_fault_handler
#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
LDR r0, =_tx_thread_system_state // Pickup address of system state
LDR r1, [r0] // Pickup system state
SUB r1, r1, #1 // Decrement
STR r1, [r0] // Store new system state
MOV r1, #0 // Build NULL value
LDR r0, =_tx_thread_current_ptr // Pickup address of current thread pointer
STR r1, [r0] // Clear current thread pointer
// Return from exception
LDR lr, =_tx_thread_schedule // Load scheduler address
SUBS pc, lr, #0 // Return to scheduler
/********************************************************************
End of MMU exception handling.
********************************************************************/
/* Reference build options and version ID to ensure they come in. */
LDR r2, =_tx_build_options // Pickup build options variable address
LDR r0, [r2, #0] // Pickup build options content
LDR r2, =_tx_version_id // Pickup version ID variable address
LDR r0, [r2, #0] // Pickup version ID content

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,140 @@
<?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.397785280">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.exe.debug.397785280" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/tx"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/tx/Debug"/>
<entry flags="RESOLVED" kind="libraryFile" name="tx" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</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.exe.debug.397785280" name="Debug" parent="com.arm.eclipse.build.config.v6.exe.debug">
<folderInfo id="com.arm.eclipse.build.config.v6.exe.debug.397785280." name="/" resourcePath="">
<toolChain id="com.arm.toolchain.v6.exe.debug.1873800485" name="Arm Compiler 6 (DS-5 built-in)" superClass="com.arm.toolchain.v6.exe.debug">
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.toolchain.v6.base.options.debug.level.291608604" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" useByScannerDiscovery="false" valueType="enumerated"/>
<option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.524053182" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" useByScannerDiscovery="false" value="Cortex-R4.VFPv3_D16" valueType="string"/>
<option id="com.arm.toolchain.v6.base.options.floatabi.379461077" name="Float ABI" superClass="com.arm.toolchain.v6.base.options.floatabi" useByScannerDiscovery="false" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
<option id="com.arm.toolchain.v6.base.options.inst.1534434276" name="Instruction set" superClass="com.arm.toolchain.v6.base.options.inst" useByScannerDiscovery="false" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
<targetPlatform id="com.arm.eclipse.build.config.v6.exe.debug.397785280..2133581333" name=""/>
<builder buildPath="${workspace_loc:/cortex-r4}/Debug" id="com.arm.toolchain.v6.builder.158492155" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.arm.toolchain.v6.builder"/>
<tool id="com.arm.tool.c.compiler.v6.1297960997" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.min" id="com.arm.tool.c.compiler.v6.base.option.optlevel.706686674" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.tool.c.compiler.v6.base.options.debug.level.331758084" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" valueType="enumerated"/>
<option id="com.arm.tool.c.compiler.v6.base.option.cpu.1198921237" name="CPU (-mcpu)" superClass="com.arm.tool.c.compiler.v6.base.option.cpu" useByScannerDiscovery="true" value="cortex-r4f" valueType="string"/>
<option id="com.arm.tool.c.compiler.v6.base.option.target.1574004324" 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.fpu.792842113" name="FPU (-mfpu)" superClass="com.arm.tool.c.compiler.v6.base.option.fpu" useByScannerDiscovery="true" value="vfpv3-d16" valueType="string"/>
<option id="com.arm.tool.c.compiler.v6.base.option.floatabi.480356500" 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.232951986" 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 id="com.arm.tool.c.compiler.v6.base.option.defmac.977735094" name="Define macro (-D)" superClass="com.arm.tool.c.compiler.v6.base.option.defmac" useByScannerDiscovery="false"/>
<option id="com.arm.tool.c.compiler.v6.base.option.preproconly.426601175" name="Preprocess only (-E)" superClass="com.arm.tool.c.compiler.v6.base.option.preproconly" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="com.arm.tool.c.compiler.v6.base.options.target.enableToolSpecificSettings.148885147" name="Enable tool specific settings" superClass="com.arm.tool.c.compiler.v6.base.options.target.enableToolSpecificSettings" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="com.arm.tool.c.compiler.v6.base.option.incpath.679205895" superClass="com.arm.tool.c.compiler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc_generic}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc_generic_module_manager}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc_generic_modules}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc_port}&quot;"/>
</option>
<inputType id="com.arm.tool.c.compiler.v6.base.input.712152796" superClass="com.arm.tool.c.compiler.v6.base.input"/>
<inputType id="com.arm.tool.cpp.compiler.v6.base.input.1604102559" superClass="com.arm.tool.cpp.compiler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.cpp.compiler.v6.1037714875" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.min" id="com.arm.tool.c.compiler.v6.base.option.optlevel.1630996211" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.tool.c.compiler.v6.base.options.debug.level.1682803592" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" valueType="enumerated"/>
</tool>
<tool id="com.arm.tool.assembler.v6.924011715" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6">
<option defaultValue="com.arm.tool.assembler.v6.base.options.debug.level.std" id="com.arm.tool.assembler.v6.base.options.debug.level.2069795992" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" useByScannerDiscovery="false" valueType="enumerated"/>
<option id="com.arm.tool.assembler.v6.base.option.cpu.1693345089" name="CPU (-mcpu)" superClass="com.arm.tool.assembler.v6.base.option.cpu" useByScannerDiscovery="false" value="cortex-r4f" valueType="string"/>
<option id="com.arm.tool.assembler.v6.base.option.target.1633066570" 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.fpu.36352317" name="FPU (-mfpu)" superClass="com.arm.tool.assembler.v6.base.option.fpu" useByScannerDiscovery="true" value="vfpv3-d16" valueType="string"/>
<option id="com.arm.tool.assembler.v6.base.option.floatabi.1661460616" 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.1927837470" 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.option.defmac.1739378921" name="Define macro (-D)" superClass="com.arm.tool.assembler.v6.base.option.defmac" useByScannerDiscovery="false"/>
<option id="com.arm.tool.assembler.v6.base.options.target.enableToolSpecificSettings.1670740136" name="Enable tool specific settings" superClass="com.arm.tool.assembler.v6.base.options.target.enableToolSpecificSettings" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="com.arm.tool.assembler.v6.base.option.flags.179733834" name="Other flags" superClass="com.arm.tool.assembler.v6.base.option.flags" useByScannerDiscovery="true" valueType="stringList">
<listOptionValue builtIn="false" value="-DTX_THUMB_MODE"/>
</option>
<inputType id="com.arm.tool.assembler.v6.base.input.796990181" superClass="com.arm.tool.assembler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.c.linker.v6.1524994417" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6">
<option id="com.arm.tool.c.linker.option.entry.1136793463" name="Image entry point (--entry)" superClass="com.arm.tool.c.linker.option.entry" useByScannerDiscovery="false" value="Start" valueType="string"/>
<option id="com.arm.tool.c.linker.option.scatter.1332412624" name="Scatter file (--scatter)" superClass="com.arm.tool.c.linker.option.scatter" useByScannerDiscovery="false" value="../sample_threadx.scat" valueType="string"/>
</tool>
<tool id="com.arm.tool.librarian.v6.799407983" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="txm_module_manager_in_place_load_original.c|txm_module_manager_in_place_load_unmodified.c|txm_module_manager_in_place_load_modified.c|txm_module_manager_mm_register_setup_new.c|txm_module_manager_internal_load_unmodified.c|txm_module_manager_in_place_load_new.c|tx_initialize_low_level_before_merging_with_startup.S|backups" 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.524725615">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.exe.release.524725615" 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.524725615" name="Release" parent="com.arm.eclipse.build.config.v6.exe.release">
<folderInfo id="com.arm.eclipse.build.config.v6.exe.release.524725615." name="/" resourcePath="">
<toolChain id="com.arm.toolchain.v6.exe.release.1762944403" name="Arm Compiler 6 (DS-5 built-in)" superClass="com.arm.toolchain.v6.exe.release">
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.toolchain.v6.base.options.debug.level.1087046132" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" valueType="enumerated"/>
<targetPlatform id="com.arm.eclipse.build.config.v6.exe.release.524725615..145961642" name=""/>
<builder buildPath="${workspace_loc:/cortex-r4}/Release" id="com.arm.toolchain.v6.builder.559511441" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.arm.toolchain.v6.builder"/>
<tool id="com.arm.tool.c.compiler.v6.131184611" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.high" id="com.arm.tool.c.compiler.v6.base.option.optlevel.488740147" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.tool.c.compiler.v6.base.options.debug.level.1314985600" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" valueType="enumerated"/>
<inputType id="com.arm.tool.c.compiler.v6.base.input.820494980" superClass="com.arm.tool.c.compiler.v6.base.input"/>
<inputType id="com.arm.tool.cpp.compiler.v6.base.input.771667771" superClass="com.arm.tool.cpp.compiler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.cpp.compiler.v6.1218809671" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.high" id="com.arm.tool.c.compiler.v6.base.option.optlevel.1008193656" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.tool.c.compiler.v6.base.options.debug.level.1610243813" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" valueType="enumerated"/>
</tool>
<tool id="com.arm.tool.assembler.v6.348130542" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6">
<option defaultValue="com.arm.tool.assembler.v6.base.options.debug.level.none" id="com.arm.tool.assembler.v6.base.options.debug.level.1819445556" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" valueType="enumerated"/>
<inputType id="com.arm.tool.assembler.v6.base.input.699090690" superClass="com.arm.tool.assembler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.c.linker.v6.595616399" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6"/>
<tool id="com.arm.tool.librarian.v6.484994551" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="backups|tx_thread_fiq_context_restore.S|tx_thread_context_save.S|tx_thread_context_restore.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="cortex-a9.com.arm.eclipse.build.project.baremetal.exe.827478944" name="Executable" projectType="com.arm.eclipse.build.project.baremetal.exe"/>
</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="/cortex-r4"/>
</configuration>
</storageModule>
<storageModule moduleId="com.arm.projectSettings" version="5.25"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
</cproject>

View File

@@ -0,0 +1,63 @@
<?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_generic_module_manager</name>
<type>2</type>
<locationURI>$%7BPARENT-5-PROJECT_LOC%7D/common_modules/module_manager/inc</locationURI>
</link>
<link>
<name>inc_generic_modules</name>
<type>2</type>
<locationURI>$%7BPARENT-5-PROJECT_LOC%7D/common_modules/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_generic_module_manager</name>
<type>2</type>
<locationURI>$%7BPARENT-5-PROJECT_LOC%7D/common_modules/module_manager/src</locationURI>
</link>
<link>
<name>src_port</name>
<type>2</type>
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/module_manager/src</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="com.arm.eclipse.build.config.v6.exe.debug.397785280" 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="1285801792837881262" 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 &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
<configuration id="com.arm.eclipse.build.config.v6.exe.release.524725615" 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="1208898303067000398" 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 &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>

View File

@@ -0,0 +1,152 @@
<?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.519865483">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.lib.debug.519865483" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/txm"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/txm/Debug"/>
<entry flags="RESOLVED" kind="libraryFile" name="txm" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</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.519865483" name="Debug" parent="com.arm.eclipse.build.config.v6.lib.debug">
<folderInfo id="com.arm.eclipse.build.config.v6.lib.debug.519865483." name="/" resourcePath="">
<toolChain id="com.arm.toolchain.v6.lib.debug.808979116" name="Arm Compiler 6 (DS-5 built-in)" superClass="com.arm.toolchain.v6.lib.debug">
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.toolchain.v6.base.options.debug.level.1877486050" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" useByScannerDiscovery="false" valueType="enumerated"/>
<option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.723936861" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" useByScannerDiscovery="false" value="Cortex-R4.VFPv3_D16" valueType="string"/>
<option id="com.arm.toolchain.v6.base.options.floatabi.979977566" name="Float ABI" superClass="com.arm.toolchain.v6.base.options.floatabi" useByScannerDiscovery="false" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
<option id="com.arm.toolchain.v6.base.options.inst.2014027180" name="Instruction set" superClass="com.arm.toolchain.v6.base.options.inst" useByScannerDiscovery="false" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
<targetPlatform id="com.arm.eclipse.build.config.v6.lib.debug.519865483..1864969534" name=""/>
<builder buildPath="${workspace_loc:/txm}/Debug" id="com.arm.toolchain.v6.builder.1850786025" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.arm.toolchain.v6.builder"/>
<tool id="com.arm.tool.c.compiler.v6.6241967" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.min" id="com.arm.tool.c.compiler.v6.base.option.optlevel.338050838" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.tool.c.compiler.v6.base.options.debug.level.1118941673" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" valueType="enumerated"/>
<option id="com.arm.tool.c.compiler.v6.base.option.incpath.973642779" name="Include path (-I)" superClass="com.arm.tool.c.compiler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc_generic_modules}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc_port}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc_generic}&quot;"/>
</option>
<option id="com.arm.tool.c.compiler.v6.base.option.cpu.220397346" name="CPU (-mcpu)" superClass="com.arm.tool.c.compiler.v6.base.option.cpu" useByScannerDiscovery="true" value="cortex-r4f" valueType="string"/>
<option id="com.arm.tool.c.compiler.v6.base.option.target.543594186" 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.fpu.396019355" name="FPU (-mfpu)" superClass="com.arm.tool.c.compiler.v6.base.option.fpu" useByScannerDiscovery="true" value="vfpv3-d16" valueType="string"/>
<option id="com.arm.tool.c.compiler.v6.base.option.floatabi.1409006855" 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.890112349" 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 id="com.arm.tool.c.compiler.v6.base.options.target.enableToolSpecificSettings.213110718" name="Enable tool specific settings" superClass="com.arm.tool.c.compiler.v6.base.options.target.enableToolSpecificSettings" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="com.arm.tool.c.compiler.v6.base.options.preproc.enableToolSpecificSettings.1682954929" name="Enable tool specific settings" superClass="com.arm.tool.c.compiler.v6.base.options.preproc.enableToolSpecificSettings" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="com.arm.tool.c.compiler.v6.base.options.debug.enableToolSpecificSettings.1982558148" name="Enable tool specific settings" superClass="com.arm.tool.c.compiler.v6.base.options.debug.enableToolSpecificSettings" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="com.arm.tool.c.compiler.v6.base.option.flags.916031554" name="Other flags" superClass="com.arm.tool.c.compiler.v6.base.option.flags" useByScannerDiscovery="true" valueType="stringList">
<listOptionValue builtIn="false" value="-frwpi"/>
<listOptionValue builtIn="false" value="-fropi"/>
</option>
<inputType id="com.arm.tool.c.compiler.v6.base.input.1705222921" superClass="com.arm.tool.c.compiler.v6.base.input"/>
<inputType id="com.arm.tool.cpp.compiler.v6.base.input.1789325577" superClass="com.arm.tool.cpp.compiler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.cpp.compiler.v6.1229585940" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.min" id="com.arm.tool.c.compiler.v6.base.option.optlevel.880645285" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.tool.c.compiler.v6.base.options.debug.level.1402765001" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" valueType="enumerated"/>
</tool>
<tool id="com.arm.tool.assembler.v6.1631473801" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6">
<option defaultValue="com.arm.tool.assembler.v6.base.options.debug.level.std" id="com.arm.tool.assembler.v6.base.options.debug.level.1909393551" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" useByScannerDiscovery="false" valueType="enumerated"/>
<option id="com.arm.tool.assembler.v6.base.option.incpath.2135819939" name="Include path (-I)" superClass="com.arm.tool.assembler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/tx}&quot;"/>
</option>
<option id="com.arm.tool.assembler.v6.base.option.cpu.986031904" name="CPU (-mcpu)" superClass="com.arm.tool.assembler.v6.base.option.cpu" useByScannerDiscovery="false" value="cortex-r4f" valueType="string"/>
<option id="com.arm.tool.assembler.v6.base.option.target.1086548395" 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.fpu.124931130" name="FPU (-mfpu)" superClass="com.arm.tool.assembler.v6.base.option.fpu" useByScannerDiscovery="true" value="vfpv3-d16" valueType="string"/>
<option id="com.arm.tool.assembler.v6.base.option.floatabi.1643867333" 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.206157906" 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.target.enableToolSpecificSettings.1161924288" name="Enable tool specific settings" superClass="com.arm.tool.assembler.v6.base.options.target.enableToolSpecificSettings" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="com.arm.tool.assembler.v6.base.options.preproc.enableToolSpecificSettings.1861899722" name="Enable tool specific settings" superClass="com.arm.tool.assembler.v6.base.options.preproc.enableToolSpecificSettings" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="com.arm.tool.assembler.v6.base.option.flags.61090532" name="Other flags" superClass="com.arm.tool.assembler.v6.base.option.flags" useByScannerDiscovery="true" valueType="stringList">
<listOptionValue builtIn="false" value="-fropi"/>
<listOptionValue builtIn="false" value="-frwpi"/>
</option>
<option id="com.arm.tool.assembler.v6.base.option.defmac.1649961135" name="Define macro (-D)" superClass="com.arm.tool.assembler.v6.base.option.defmac" useByScannerDiscovery="false"/>
<inputType id="com.arm.tool.assembler.v6.base.input.1161172462" superClass="com.arm.tool.assembler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.c.linker.v6.2136164467" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6"/>
<tool id="com.arm.tool.librarian.v6.1634398245" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings">
<externalSettings containerId="tx;" factoryId="org.eclipse.cdt.core.cfg.export.settings.sipplier">
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/tx"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/tx/Debug"/>
<entry flags="RESOLVED" kind="libraryFile" name="tx" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
</storageModule>
</cconfiguration>
<cconfiguration id="com.arm.eclipse.build.config.v6.lib.release.2096916400">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.lib.release.2096916400" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/txm"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/txm/Release"/>
<entry flags="RESOLVED" kind="libraryFile" name="txm" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</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.2096916400" name="Release" parent="com.arm.eclipse.build.config.v6.lib.release">
<folderInfo id="com.arm.eclipse.build.config.v6.lib.release.2096916400." name="/" resourcePath="">
<toolChain id="com.arm.toolchain.v6.lib.release.775914121" name="Arm Compiler 6 (DS-5 built-in)" superClass="com.arm.toolchain.v6.lib.release">
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.toolchain.v6.base.options.debug.level.1216865522" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" valueType="enumerated"/>
<targetPlatform id="com.arm.eclipse.build.config.v6.lib.release.2096916400..112800518" name=""/>
<builder buildPath="${workspace_loc:/txm}/Release" id="com.arm.toolchain.v6.builder.614719204" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.arm.toolchain.v6.builder"/>
<tool id="com.arm.tool.c.compiler.v6.1211197993" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.high" id="com.arm.tool.c.compiler.v6.base.option.optlevel.1084198370" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.tool.c.compiler.v6.base.options.debug.level.28182833" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" valueType="enumerated"/>
<inputType id="com.arm.tool.c.compiler.v6.base.input.389178055" superClass="com.arm.tool.c.compiler.v6.base.input"/>
<inputType id="com.arm.tool.cpp.compiler.v6.base.input.1669523083" superClass="com.arm.tool.cpp.compiler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.cpp.compiler.v6.730735832" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6">
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.high" id="com.arm.tool.c.compiler.v6.base.option.optlevel.1118429846" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" valueType="enumerated"/>
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.tool.c.compiler.v6.base.options.debug.level.1420207151" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" valueType="enumerated"/>
</tool>
<tool id="com.arm.tool.assembler.v6.272655679" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6">
<option defaultValue="com.arm.tool.assembler.v6.base.options.debug.level.none" id="com.arm.tool.assembler.v6.base.options.debug.level.753628661" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" valueType="enumerated"/>
<inputType id="com.arm.tool.assembler.v6.base.input.257137608" superClass="com.arm.tool.assembler.v6.base.input"/>
</tool>
<tool id="com.arm.tool.c.linker.v6.680343036" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6"/>
<tool id="com.arm.tool.librarian.v6.281403224" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="txm.com.arm.eclipse.build.project.v6.lib.837111164" name="Static Library" projectType="com.arm.eclipse.build.project.v6.lib"/>
</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="/txm"/>
</configuration>
<configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/txm"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
</cproject>

View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>txm</name>
<comment></comment>
<projects>
<project>tx</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.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_generic_modules</name>
<type>2</type>
<locationURI>$%7BPARENT-5-PROJECT_LOC%7D/common_modules/inc</locationURI>
</link>
<link>
<name>inc_port</name>
<type>2</type>
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/inc</locationURI>
</link>
<link>
<name>src_generic_module</name>
<type>2</type>
<locationURI>$%7BPARENT-5-PROJECT_LOC%7D/common_modules/module_lib/src</locationURI>
</link>
<link>
<name>src_port</name>
<type>2</type>
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/module_lib/src</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="com.arm.eclipse.build.config.v6.lib.debug.519865483" 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="1219961745659432110" 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 &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
<configuration id="com.arm.eclipse.build.config.v6.lib.release.2096916400" 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="1208898303067000398" 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 &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>

View File

@@ -0,0 +1,360 @@
/**************************************************************************/
/* */
/* 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-R4/AC6 */
/* 6.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 */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */
/* macro definition, */
/* resulting in version 6.1.6 */
/* */
/**************************************************************************/
#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 intrinsics. */
#include "arm_compat.h"
/* 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; \
VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
ULONG tx_thread_module_user_mode; \
VOID *tx_thread_module_kernel_stack_start; \
VOID *tx_thread_module_kernel_stack_end; \
ULONG tx_thread_module_kernel_stack_size; \
VOID *tx_thread_module_stack_ptr; \
VOID *tx_thread_module_stack_start; \
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved;
#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 VOID *tx_event_flags_group_module_instance; \
VOID (*tx_event_flags_group_set_module_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *group_ptr);
#define TX_MUTEX_EXTENSION
#define TX_QUEUE_EXTENSION VOID *tx_queue_module_instance; \
VOID (*tx_queue_send_module_notify)(struct TX_QUEUE_STRUCT *queue_ptr);
#define TX_SEMAPHORE_EXTENSION VOID *tx_semaphore_module_instance; \
VOID (*tx_semaphore_put_module_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr);
#define TX_TIMER_EXTENSION VOID *tx_timer_module_instance; \
VOID (*tx_timer_module_expiration_function)(ULONG id);
/* 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. */
#ifndef __thumb
#define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \
b = (ULONG) __clz((unsigned int) m); \
b = 31 - b;
#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. */
#ifndef __thumb
#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save_disabled;
#ifdef TX_ENABLE_FIQ_SUPPORT
/* IRQ and FIQ support. */
#define TX_DISABLE __memory_changed(), interrupt_save_disabled = __disable_irq(); \
__disable_fiq();
#define TX_RESTORE if (!interrupt_save_disabled) \
{ \
__enable_irq(); \
__enable_fiq(); \
}
#else
#define TX_DISABLE __memory_changed(), interrupt_save_disabled = __disable_irq();
#define TX_RESTORE if (!interrupt_save_disabled) \
{ \
__enable_irq(); \
}
#endif
#else
unsigned int _tx_thread_interrupt_disable(void);
unsigned int _tx_thread_interrupt_restore(UINT old_posture);
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
#endif
/* Define VFP extension for the Cortex-R4. 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-R4/AC6 Version 6.1.6 *";
#else
extern CHAR _tx_version_id[];
#endif
#endif

View File

@@ -0,0 +1,366 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the basic module constants, interface structures, */
/* and function prototypes. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
#ifndef TXM_MODULE_PORT_H
#define TXM_MODULE_PORT_H
/* It is assumed that the base ThreadX tx_port.h file has been modified to add the
following extensions to the ThreadX thread control block (this code should replace
the corresponding macro define in tx_port.h):
#define TX_THREAD_EXTENSION_2 ULONG tx_thread_vfp_enable; \
VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
ULONG tx_thread_module_user_mode; \
VOID *tx_thread_module_kernel_stack_start; \
VOID *tx_thread_module_kernel_stack_end; \
ULONG tx_thread_module_kernel_stack_size; \
VOID *tx_thread_module_stack_ptr; \
VOID *tx_thread_module_stack_start; \
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved;
The following extensions must also be defined in tx_port.h:
#define TX_EVENT_FLAGS_GROUP_EXTENSION VOID *tx_event_flags_group_module_instance; \
VOID (*tx_event_flags_group_set_module_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *group_ptr);
#define TX_QUEUE_EXTENSION VOID *tx_queue_module_instance; \
VOID (*tx_queue_send_module_notify)(struct TX_QUEUE_STRUCT *queue_ptr);
#define TX_SEMAPHORE_EXTENSION VOID *tx_semaphore_module_instance; \
VOID (*tx_semaphore_put_module_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr);
#define TX_TIMER_EXTENSION VOID *tx_timer_module_instance; \
VOID (*tx_timer_module_expiration_function)(ULONG id);
*/
/* Size of module heap. */
#define TXM_MODULE_HEAP_SIZE 1024
/* Define the kernel stack size for a module thread. */
#ifndef TXM_MODULE_KERNEL_STACK_SIZE
#define TXM_MODULE_KERNEL_STACK_SIZE 1024
#endif
/* Defined, these options allows a memory-protected module to access kernel objects.
For example, when a module needs to send/receive a message from a kernel queue.
This does not allow modules to create or delete objects outside of their memory.
Default setting for these values is undefined. */
/* #define TXM_MODULE_ENABLE_KERNEL_BLOCK_POOL_ACCESS */
/* #define TXM_MODULE_ENABLE_KERNEL_BYTE_POOL_ACCESS */
/* #define TXM_MODULE_ENABLE_KERNEL_EVENT_FLAGS_ACCESS */
/* #define TXM_MODULE_ENABLE_KERNEL_MUTEX_ACCESS */
/* #define TXM_MODULE_ENABLE_KERNEL_QUEUE_ACCESS */
/* #define TXM_MODULE_ENABLE_KERNEL_SEMAPHORE_ACCESS */
/* For the following 3 access control settings, change TEX and C, B, S (bits 5 through 0)
* to reflect your system memory attributes (cache, shareable, memory type). */
/* Code region access control: read-only, outer & inner write-back, normal memory, shareable. */
#define TXM_MODULE_MPU_CODE_ACCESS_CONTROL 0x00000607
/* Data region access control: execute never, read/write, outer & inner write-back, normal memory, shareable. */
#define TXM_MODULE_MPU_DATA_ACCESS_CONTROL 0x00001307
/* Shared region access control: execute never, read-only, outer & inner write-back, normal memory, shareable. */
#define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x00001207
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
#define TXM_MODULE_RVDS_COMPILER 0x01000000
#define TXM_MODULE_GNU_COMPILER 0x02000000
#define TXM_MODULE_COMPILER_MASK 0xFF000000
#define TXM_MODULE_OPTIONS_MASK 0x000000FF
/* Define the properties for this particular module port. */
#define TXM_MODULE_MEMORY_PROTECTION_ENABLED
#ifdef TXM_MODULE_MEMORY_PROTECTION_ENABLED
#define TXM_MODULE_REQUIRE_ALLOCATED_OBJECT_MEMORY
#define TXM_MODULE_MANAGER_DISABLE_INTERRUPT_CONTROL
#else
#define TXM_MODULE_REQUIRE_LOCAL_OBJECT_MEMORY
#endif
#define TXM_MODULE_USER_MODE 0x00000001
#define TXM_MODULE_MEMORY_PROTECTION 0x00000001
/* Define the supported options for this module. */
#define TXM_MODULE_MANAGER_SUPPORTED_OPTIONS (TXM_MODULE_MEMORY_PROTECTION)
#define TXM_MODULE_MANAGER_REQUIRED_OPTIONS 0
/* Define offset adjustments according to the compiler used to build the module. */
#define TXM_MODULE_IAR_SHELL_ADJUST 24
#define TXM_MODULE_IAR_START_ADJUST 28
#define TXM_MODULE_IAR_STOP_ADJUST 32
#define TXM_MODULE_IAR_CALLBACK_ADJUST 44
#define TXM_MODULE_RVDS_SHELL_ADJUST 0
#define TXM_MODULE_RVDS_START_ADJUST 0
#define TXM_MODULE_RVDS_STOP_ADJUST 0
#define TXM_MODULE_RVDS_CALLBACK_ADJUST 0
#define TXM_MODULE_GNU_SHELL_ADJUST 24
#define TXM_MODULE_GNU_START_ADJUST 28
#define TXM_MODULE_GNU_STOP_ADJUST 32
#define TXM_MODULE_GNU_CALLBACK_ADJUST 44
/* Define other module port-specific constants. */
/* Define INLINE_DECLARE to inline for IAR compiler. */
#define INLINE_DECLARE inline
/* Define the number of MPU entries assigned to the code and data sections.
On Cortex-R parts, there are 12 total entries. ThreadX uses one for access
to the kernel entry function, thus 11 remain for code and data protection. */
#define TXM_MODULE_MPU_TOTAL_ENTRIES 12
#define TXM_MODULE_MPU_CODE_ENTRIES 4
#define TXM_MODULE_MPU_DATA_ENTRIES 4
#define TXM_MODULE_MPU_SHARED_ENTRIES 3
#define TXM_MODULE_MPU_KERNEL_ENTRY_INDEX 0
#define TXM_MODULE_MPU_SHARED_INDEX 9
/* There are 3 registers to set up each MPU region: DRACR, DRBAR, DRSR. */
#define TXM_MODULE_MPU_REGISTER_COUNT 3
#define TXM_ENABLE_REGION 0x01
/* Shared memory region attributes. */
#define TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE 1
#define TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT 0x00000100
typedef struct TXM_MODULE_MPU_INFO_STRUCT
{
ULONG txm_module_mpu_region_address;
ULONG txm_module_mpu_region_size;
ULONG txm_module_mpu_region_attributes;
} TXM_MODULE_MPU_INFO;
/* Define the port-extensions to the module manager instance structure. */
#define TXM_MODULE_MANAGER_PORT_EXTENSION \
TXM_MODULE_MPU_INFO txm_module_instance_mpu_registers[TXM_MODULE_MPU_TOTAL_ENTRIES]; \
ULONG txm_module_instance_shared_memory_count; \
ULONG txm_module_instance_shared_memory_address[TXM_MODULE_MPU_SHARED_ENTRIES]; \
ULONG txm_module_instance_shared_memory_length[TXM_MODULE_MPU_SHARED_ENTRIES];
/* Define the memory fault information structure that is populated when a memory fault occurs. */
typedef struct TXM_MODULE_MANAGER_MEMORY_FAULT_INFO_STRUCT
{
TX_THREAD *txm_module_manager_memory_fault_info_thread_ptr;
VOID *txm_module_manager_memory_fault_info_code_location;
ULONG txm_module_manager_memory_fault_info_dfar;
ULONG txm_module_manager_memory_fault_info_dfsr;
ULONG txm_module_manager_memory_fault_info_ifar;
ULONG txm_module_manager_memory_fault_info_ifsr;
ULONG txm_module_manager_memory_fault_info_sp;
ULONG txm_module_manager_memory_fault_info_r0;
ULONG txm_module_manager_memory_fault_info_r1;
ULONG txm_module_manager_memory_fault_info_r2;
ULONG txm_module_manager_memory_fault_info_r3;
ULONG txm_module_manager_memory_fault_info_r4;
ULONG txm_module_manager_memory_fault_info_r5;
ULONG txm_module_manager_memory_fault_info_r6;
ULONG txm_module_manager_memory_fault_info_r7;
ULONG txm_module_manager_memory_fault_info_r8;
ULONG txm_module_manager_memory_fault_info_r9;
ULONG txm_module_manager_memory_fault_info_r10;
ULONG txm_module_manager_memory_fault_info_r11;
ULONG txm_module_manager_memory_fault_info_r12;
ULONG txm_module_manager_memory_fault_info_lr;
ULONG txm_module_manager_memory_fault_info_cpsr;
} TXM_MODULE_MANAGER_MEMORY_FAULT_INFO;
#define TXM_MODULE_MANAGER_FAULT_INFO \
TXM_MODULE_MANAGER_MEMORY_FAULT_INFO _txm_module_manager_memory_fault_info;
/* Define the macro to check the stack available in dispatch. */
#define TXM_MODULE_MANAGER_CHECK_STACK_AVAILABLE
/* Define the macro to check the module properties. */
#define TXM_MODULE_MANAGER_CHECK_PROPERTIES(properties) \
if ((properties & _txm_module_manager_properties_supported) != (properties & ~((ULONG) TXM_MODULE_COMPILER_MASK))) \
{ \
_tx_mutex_put(&_txm_module_manager_mutex); \
return(TXM_MODULE_INVALID_PROPERTIES); \
} \
if ((_txm_module_manager_properties_required & properties) != _txm_module_manager_properties_required) \
{ \
_tx_mutex_put(&_txm_module_manager_mutex); \
return(TXM_MODULE_INVALID_PROPERTIES); \
}
/* Define the macro to check the code alignment. */
#define TXM_MODULE_MANAGER_CHECK_CODE_ALIGNMENT(module_location, code_alignment) \
{ \
ULONG temp; \
temp = (ULONG) module_location; \
temp = temp & (code_alignment - 1); \
if (temp) \
{ \
_tx_mutex_put(&_txm_module_manager_mutex); \
return(TXM_MODULE_ALIGNMENT_ERROR); \
} \
}
/* Define the macro to adjust the alignment and size for code/data areas. */
#define TXM_MODULE_MANAGER_ALIGNMENT_ADJUST(module_preamble, code_size, code_alignment, data_size, data_alignment) _txm_module_manager_alignment_adjust(module_preamble, &code_size, &code_alignment, &data_size, &data_alignment);
/* Define the macro to adjust the symbols in the module preamble. */
#define TXM_MODULE_MANAGER_CALCULATE_ADJUSTMENTS(properties, shell_function_adjust, start_function_adjust, stop_function_adjust, callback_function_adjust) \
if ((properties & TXM_MODULE_COMPILER_MASK) == TXM_MODULE_IAR_COMPILER) \
{ \
shell_function_adjust = TXM_MODULE_IAR_SHELL_ADJUST; \
start_function_adjust = TXM_MODULE_IAR_START_ADJUST; \
stop_function_adjust = TXM_MODULE_IAR_STOP_ADJUST; \
callback_function_adjust = TXM_MODULE_IAR_CALLBACK_ADJUST; \
} \
else if ((properties & TXM_MODULE_COMPILER_MASK) == TXM_MODULE_RVDS_COMPILER) \
{ \
shell_function_adjust = TXM_MODULE_RVDS_SHELL_ADJUST; \
start_function_adjust = TXM_MODULE_RVDS_START_ADJUST; \
stop_function_adjust = TXM_MODULE_RVDS_STOP_ADJUST; \
callback_function_adjust = TXM_MODULE_RVDS_CALLBACK_ADJUST; \
} \
else \
{ \
shell_function_adjust = TXM_MODULE_GNU_SHELL_ADJUST; \
start_function_adjust = TXM_MODULE_GNU_START_ADJUST; \
stop_function_adjust = TXM_MODULE_GNU_STOP_ADJUST; \
callback_function_adjust = TXM_MODULE_GNU_CALLBACK_ADJUST; \
}
/* Define the macro to populate the thread control block with module port-specific information.
Check if the module is in user mode and set up txm_module_thread_entry_info_kernel_call_dispatcher accordingly.
*/
#define TXM_MODULE_MANAGER_THREAD_SETUP(thread_ptr, module_instance) \
thread_ptr -> tx_thread_module_current_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION; \
thread_ptr -> tx_thread_module_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION; \
if (thread_ptr -> tx_thread_module_user_mode) \
{ \
thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher = _txm_module_manager_user_mode_entry; \
} \
else \
{ \
thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher = _txm_module_manager_kernel_dispatch; \
}
/* Define the macro to populate the module control block with module port-specific information.
If memory protection is enabled, set up the MPU registers.
*/
#define TXM_MODULE_MANAGER_MODULE_SETUP(module_instance) \
if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION) \
{ \
_txm_module_manager_mm_register_setup(module_instance); \
} \
else \
{ \
/* Do nothing. */ \
}
/* Define the macro to perform port-specific functions when unloading the module. */
/* Nothing needs to be done for this port. */
#define TXM_MODULE_MANAGER_MODULE_UNLOAD(module_instance)
/* Define the macros to perform port-specific checks when passing pointers to the kernel. */
/* Define macro to make sure object is inside the module's data. */
#define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \
_txm_module_manager_inside_data_check(module_instance, obj_ptr, obj_size)
/* Define some internal prototypes to this module port. */
#ifndef TX_SOURCE_CODE
#define txm_module_manager_memory_fault_notify _txm_module_manager_memory_fault_notify
#endif
#define TXM_MODULE_MANAGER_ADDITIONAL_PROTOTYPES \
VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, ULONG *code_size, ULONG *code_alignment, ULONG *data_size, ULONG *data_alignment); \
ULONG _txm_module_manager_data_pointer_check(TXM_MODULE_INSTANCE *module_instance, ULONG pointer); \
VOID _txm_module_manager_memory_fault_handler(VOID); \
UINT _txm_module_manager_memory_fault_notify(VOID (*notify_function)(TX_THREAD *, TXM_MODULE_INSTANCE *)); \
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance); \
ULONG _txm_power_of_two_block_size(ULONG size); \
ULONG _txm_module_manager_calculate_srd_bits(ULONG block_size, ULONG length); \
ULONG _txm_module_manager_region_size_get(ULONG block_size); \
UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE obj_ptr, UINT obj_size);
#define TXM_MODULE_MANAGER_VERSION_ID \
CHAR _txm_module_manager_version_id[] = \
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-R4/MPU/ARM Version 6.1 *";
#endif

View 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 */
;/** */
;/** Module */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
.global __scatterload
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
.eabi_attribute Tag_ABI_PCS_RO_data, 1
.eabi_attribute Tag_ABI_PCS_R9_use, 1
.eabi_attribute Tag_ABI_PCS_RW_data, 2
.arm
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_initialize Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function initializes the module c runtime. */
/* */
/* INPUT */
/* */
/* heap_base Pointer to bottom of heap */
/* heap_top Pointer to top of heap */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* __scatterload Initialize C runtime */
/* __rt_lib_init Initialize heap */
/* */
/* CALLED BY */
/* */
/* _txm_module_thread_shell_entry Start module thread */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _txm_module_initialize(VOID *heap_base, VOID *heap_top) */
.global _txm_module_initialize
.type _txm_module_initialize, %function
_txm_module_initialize:
PUSH {r0-r12,lr} // Save dregs and LR
B __scatterload // Call ARM func to initialize variables
.global __rt_entry
.type __rt_entry, %function
__rt_entry:
POP {r0-r1}
BL __rt_lib_init
POP {r2-r12,lr} // Restore dregs and LR
BX lr // Return to caller

View File

@@ -0,0 +1,176 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module */
/** */
/**************************************************************************/
/**************************************************************************/
#ifndef TXM_MODULE
#define TXM_MODULE
#endif
#ifndef TX_SOURCE_CODE
#define TX_SOURCE_CODE
#endif
/* Include necessary system files. */
#include "txm_module.h"
#include "tx_thread.h"
/* Define the global module entry pointer from the start thread of the module. */
TXM_MODULE_THREAD_ENTRY_INFO *_txm_module_entry_info;
/* Define the dispatch function pointer used in the module implementation. */
ULONG (*_txm_module_kernel_call_dispatcher)(ULONG kernel_request, ULONG param_1, ULONG param_2, ULONG param3);
/* Define the module's heap and align it to 8 bytes. */
__attribute__((aligned(8))) UCHAR txm_heap[TXM_MODULE_HEAP_SIZE];
/* Must use two region memory - heap and stack are not next to each other. */
__asm(".global __use_two_region_memory\n\t");
/* Use our asm routine that calls the ARM code to initialize data and heap. */
extern VOID _txm_module_initialize(VOID *heap_base, VOID *heap_top);
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_thread_shell_entry Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function calls the specified entry function of the thread. It */
/* also provides a place for the thread's entry function to return. */
/* If the thread returns, this function places the thread in a */
/* "COMPLETED" state. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to current thread */
/* thread_info Pointer to thread entry info */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _txm_module_initialize cstartup initialization */
/* thread_entry Thread's entry function */
/* tx_thread_resume Resume the module callback thread */
/* _txm_module_thread_system_suspend Module thread suspension routine */
/* */
/* CALLED BY */
/* */
/* Initial thread stack frame */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _txm_module_thread_shell_entry(TX_THREAD *thread_ptr, TXM_MODULE_THREAD_ENTRY_INFO *thread_info)
{
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
VOID (*entry_exit_notify)(TX_THREAD *, UINT);
#endif
/* Determine if this is the start thread. If so, we must prepare the module for
execution. If not, simply skip the C startup code. */
if (thread_info -> txm_module_thread_entry_info_start_thread)
{
/* Initialize the ARM C environment. */
_txm_module_initialize(&txm_heap[0], &txm_heap[TXM_MODULE_HEAP_SIZE-1]);
/* Save the entry info pointer, for later use. */
_txm_module_entry_info = thread_info;
/* Save the kernel function dispatch address. This is used to make all resident calls from
the module. */
_txm_module_kernel_call_dispatcher = thread_info -> txm_module_thread_entry_info_kernel_call_dispatcher;
/* Ensure that we have a valid pointer. */
while (!_txm_module_kernel_call_dispatcher)
{
/* Loop here, if an error is present getting the dispatch function pointer!
An error here typically indicates the resident portion of _tx_thread_schedule
is not supporting the trap to obtain the function pointer. */
}
/* Resume the module's callback thread, already created in the manager. */
_txe_thread_resume(thread_info -> txm_module_thread_entry_info_callback_request_thread);
}
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
/* Pickup the entry/exit application callback routine. */
entry_exit_notify = thread_info -> txm_module_thread_entry_info_exit_notify;
/* Determine if an application callback routine is specified. */
if (entry_exit_notify != TX_NULL)
{
/* Yes, notify application that this thread has been entered! */
(entry_exit_notify)(thread_ptr, TX_THREAD_ENTRY);
}
#endif
/* Call current thread's entry function. */
(thread_info -> txm_module_thread_entry_info_entry) (thread_info -> txm_module_thread_entry_info_parameter);
/* Suspend thread with a "completed" state. */
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
/* Pickup the entry/exit application callback routine again. */
entry_exit_notify = thread_info -> txm_module_thread_entry_info_exit_notify;
/* Determine if an application callback routine is specified. */
if (entry_exit_notify != TX_NULL)
{
/* Yes, notify application that this thread has exited! */
(entry_exit_notify)(thread_ptr, TX_THREAD_EXIT);
}
#endif
/* Call actual thread suspension routine. */
_txm_module_thread_system_suspend(thread_ptr);
#ifdef TX_SAFETY_CRITICAL
/* If we ever get here, raise safety critical exception. */
TX_SAFETY_CRITICAL_EXCEPTION(__FILE__, __LINE__, 0);
#endif
}

View 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"
*/
#define IRQ_MODE 0x12 // IRQ mode
#define SYS_MODE 0x1F // SYS mode
#define THUMB_MASK 0x20 // Thumb bit mask
.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
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_isr_exit
#endif
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_restore Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, 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 */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.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 var
LDR r2, [r3, #0] // Pickup system state
SUB r2, r2, #1 // Decrement the counter
STR r2, [r3, #0] // 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
SUBS pc, lr, #0 // 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, #0] // 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, #0] // 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, #0] // 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
SUBS pc, lr, #0 // 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)
CPS #SYS_MODE // Switch to SYS mode to save context on thread stack
STR r1, [sp, #-4]! // Save point of interrupt
STMDB sp!, {r4-r12, lr} // Save registers
MOV r4, r3 // Save SPSR in r4
CPS #IRQ_MODE // Switch back to IRQ mode
LDMIA sp!, {r0-r3} // Recover r0-r3
CPS #SYS_MODE // Switch to SYS mode to save remaining context on thread stack
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, #0] // Pickup current thread pointer
#ifdef __ARM_FP
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!, {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, #0] // 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, #0] // 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, #0] // Clear current thread pointer
/* Return to the scheduler. */
/* _tx_thread_schedule(); */
CPS #IRQ_MODE // Enter IRQ mode
MRS r1, SPSR // Get SPSR
ORR r1, r1, #SYS_MODE // Change to SYS Mode
BIC r1, r1, #THUMB_MASK // Clear thumb bit
MSR SPSR_cxsf, r1 // Put SYS Mode in SPSR
LDR lr, =_tx_thread_schedule // Load scheduler address
SUBS pc, lr, #0 // Return to scheduler
/* } */
__tx_thread_idle_system_restore:
/* Just return back to the scheduler! */
LDR lr, =_tx_thread_schedule // Load scheduler address
SUBS pc, lr, #0 // Return to scheduler
/* } */

View 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" */
.global _tx_thread_system_state
.global _tx_thread_current_ptr
.global __tx_irq_processing_return
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_isr_enter
#endif
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_save Cortex-R4/AC6 */
/* 6.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 */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.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 var
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
/* 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, #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!
/* 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
/* } */
/* } */

View File

@@ -0,0 +1,260 @@
/**************************************************************************/
/* */
/* 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" */
#define FIQ_MODE 0x11 // FIQ mode
#define SVC_MODE 0x13 // SVC mode
#define MODE_MASK 0x1F // Mode mask
#define 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
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_isr_exit
#endif
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fiq_context_restore Cortex-R4/AC6 */
/* 6.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 */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.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 var
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
SUBS pc, lr, #0 // 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 and POI
MSR SPSR_cxsf, r0 // Put SPSR back
LDMIA sp!, {r0-r3} // Recover r0-r3
SUBS pc, lr, #0 // 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)
CPS #SVC_MODE // Switch to SVC mode to save context on thread stack
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
CPS #FIQ_MODE // Switch back to FIQ mode
LDMIA sp!, {r0-r3} // Recover r0-r3
CPS #SVC_MODE // Switch to SVC mode to save remaining context on thread stack
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 __ARM_FP
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 FIQ save
VMRS r2, FPSCR // Pickup the FPSCR
STR r2, [sp, #-4]! // Save FPSCR
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
CPS #SVC_MODE // Switch to SVC mode
B _tx_thread_schedule // Return to scheduler
/* } */

View File

@@ -0,0 +1,209 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/**************************************************************************/
/**************************************************************************/
#ifdef TX_ENABLE_FIQ_SUPPORT
/* #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
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_isr_enter
#endif
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fiq_context_save Cortex-R4/AC6 */
/* 6.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 */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.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 var
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
/* } */
/* } */
#endif

View 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" */
#define FIQ_MODE 0x11 // FIQ Mode bits
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fiq_nesting_end Cortex-R4/AC6 */
/* 6.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 */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.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
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if // Disable IRQ and FIQ interrupts
#else
CPSID i // Disable IRQ interrupts
#endif
LDMIA sp!, {r1, lr} // Pickup saved lr (and r1 throw-away for
// 8-byte alignment logic)
CPS #FIQ_MODE // Switch back to FIQ mode
BX r3 // Return to caller
/* } */

View File

@@ -0,0 +1,96 @@
/**************************************************************************/
/* */
/* 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 SYS_MODE 0x12 // System mode
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fiq_nesting_start Cortex-R4/AC6 */
/* 6.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 */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.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
CPS #SYS_MODE // Switch to 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
CPSIE f // Enable FIQ interrupts
BX r3 // Return to caller
/* } */

View File

@@ -0,0 +1,102 @@
/**************************************************************************/
/* */
/* 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
#define INT_MASK 0xC0 // Interrupt bit mask
#else
#define INT_MASK 0x80 // Interrupt bit mask
#endif
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_control Cortex-R4/AC6 */
/* 6.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 */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.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
BIC r1, r3, #INT_MASK // 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
AND r0, r3, #INT_MASK // Return previous interrupt mask
BX lr // Return to caller
/* } */

View File

@@ -0,0 +1,96 @@
/**************************************************************************/
/* */
/* 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_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_disable Cortex-R4/AC6 */
/* 6.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 */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.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
BX lr // Return to caller
/* } */

View File

@@ -0,0 +1,90 @@
/**************************************************************************/
/* */
/* 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_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_restore Cortex-R4/AC6 */
/* 6.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 */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.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
BX lr // Return to caller
/* } */

View File

@@ -0,0 +1,105 @@
/**************************************************************************/
/* */
/* 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 IRQ_MODE 0x12 // IRQ Mode bits
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_irq_nesting_end Cortex-R4/AC6 */
/* 6.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 */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.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
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if // Disable IRQ and FIQ interrupts
#else
CPSID i // Disable IRQ interrupts
#endif
LDMIA sp!, {r1, lr} // Pickup saved lr (and r1 throw-away for
// 8-byte alignment logic)
CPS #IRQ_MODE // Switch back to IRQ mode
BX r3 // Return to caller
/* } */

View File

@@ -0,0 +1,96 @@
/**************************************************************************/
/* */
/* 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 SYS_MODE 0x1F // System mode bits
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_irq_nesting_start Cortex-R4/AC6 */
/* 6.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 */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.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
CPS #SYS_MODE // Switch to 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
CPSIE i // Enable IRQ interrupts
BX r3 // Return to caller
/* } */

View File

@@ -0,0 +1,469 @@
/**************************************************************************/
/* */
/* 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
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_thread_enter
#endif
#define THUMB_MASK 0x20 // Thumb bit (5) of CPSR/SPSR.
#define IRQ_MODE 0x12 // IRQ mode
#define USR_MODE 0x10 // USR mode
#define SVC_MODE 0x13 // SVC mode
#define SYS_MODE 0x1F // SYS mode
#define MODE_MASK 0x1F // Mode mask
.arm
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, 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 */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_schedule(VOID) */
/* { */
.global _tx_thread_schedule
.type _tx_thread_schedule, "function"
_tx_thread_schedule:
/* Enter the scheduler. */
SVC 0
/* We should never get here - ever! */
_tx_scheduler_fault__:
B _tx_scheduler_fault__
/* } */
/**************************************************************************/
/**************************************************************************/
/* SWI_Handler */
/**************************************************************************/
.global SWI_Handler
.type SWI_Handler, "function"
.global __tx_svc_interrupt
.type __tx_svc_interrupt, "function"
SWI_Handler:
__tx_svc_interrupt:
STMFD sp!, {r0-r3, r12, lr} // Store the registers
MOV r1, sp // Set pointer to parameters
MRS r0, spsr // Get spsr
STMFD sp!, {r0, r3} // Store spsr onto stack and another
// register to maintain 8-byte-aligned stack
TST r0, #THUMB_MASK // Occurred in Thumb state?
LDRHNE r0, [lr,#-2] // Yes: Load halfword and...
BICNE r0, r0, #0xFF00 // ...extract comment field
LDREQ r0, [lr,#-4] // No: Load word and...
BICEQ r0, r0, #0xFF000000 // ...extract comment field
// r0 now contains SVC number
// r1 now contains pointer to stacked registers
CMP r0, #0 // Is it a schedule request?
BEQ _tx_handler_svc_schedule // Yes, go there
CMP r0, #1 // Is it a system mode enter request?
BEQ _tx_handler_svc_super_enter // Yes, go there
CMP r0, #2 // Is it a system mode exit request?
BEQ _tx_handler_svc_super_exit // Yes, go there
LDR r2, =0x123456
CMP r0, r2 // Is it an ARM request?
BEQ _tx_handler_svc_arm // Yes, go there
/**************************************************************************/
/* Unknown SVC argument */
/**************************************************************************/
/* Unrecognized service call */
_tx_handler_svc_unrecognized:
_tx_handler_svc_unrecognized_loop: /* We should never get here */
B _tx_handler_svc_unrecognized_loop
/**************************************************************************/
/* SVC 1 */
/**************************************************************************/
/* At this point we have an SVC 1, which means we are entering
supervisor mode to service a kernel call. */
_tx_handler_svc_super_enter:
// Make sure that we have been called from the system mode enter location (security).
LDR r2, =_txm_system_mode_enter // Load the address of the known call point
SUB r1, lr, #4 // Calculate the address of the actual call
CMP r1, r2 // Did we come from txm_module_manager_user_mode_entry?
BNE _tx_handler_svc_unrecognized // Return to where we came
// Clear the user mode flag in the thread structure.
LDR r1, =_tx_thread_current_ptr // Load the current thread pointer address
LDR r2, [r1] // Load current thread location from the pointer (pointer indirection)
MOV r1, #0 // Load the new user mode flag value (user mode flag clear -> not user mode -> system)
STR r1, [r2, #0x9C] // Clear the current user mode selection for thread
// Now we enter the system mode and return.
LDMFD sp!, {r0, r3} // Get spsr from the stack
BIC r0, r0, #MODE_MASK // clear mode field
ORR r0, r0, #SYS_MODE // system mode code
MSR SPSR_cxsf, r0 // Restore the spsr
LDR r1, [r2, #0xA8] // Load the module kernel stack pointer
CPS #SYS_MODE // Switch to SYS mode
MOV r3, sp // Grab thread stack pointer
MOV sp, r1 // Set SP to kernel stack pointer
CPS #SVC_MODE // Switch back to SVC mode
STR r3, [r2, #0xB0] // Save thread stack pointer
#ifndef TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE
LDR r3, [r2, #0xAC] // Load the module kernel stack size
STR r3, [r2, #20] // Set stack size
LDRD r0, r1, [r2, #0xA4] // Load the module kernel stack start and end
STRD r0, r1, [r2, #0x0C] // Set stack start and end
#endif
LDMFD sp!, {r0-r3, r12, pc}^ // Restore the registers and return
/**************************************************************************/
/* SVC 2 */
/**************************************************************************/
/* At this point we have an SVC 2, which means we are exiting
supervisor mode after servicing a kernel call. */
_tx_handler_svc_super_exit:
// Make sure that we have been called from the system mode exit location (security).
LDR r2, =_txm_system_mode_exit // Load the address of the known call point
SUB r1, lr, #4 // Calculate the address of the actual call
CMP r1, r2 // Did we come from txm_module_manager_user_mode_entry?
BNE _tx_handler_svc_unrecognized // Return to where we came
// Set the user mode flag into the thread structure.
LDR r1, =_tx_thread_current_ptr // Load the current thread pointer address
LDR r2, [r1] // Load the current thread location from the pointer (pointer indirection)
MOV r1, #1 // Load the new user mode flag value (user mode enabled -> not system anymore)
STR r1, [r2, #0x9C] // Clear the current user mode selection for thread
// Now we enter user mode (exit the system mode) and return.
LDMFD sp!, {r0, r3} // Get spsr from the stack
BIC r0, r0, #MODE_MASK // clear mode field
ORR r0, r0, #USR_MODE // user mode code
MSR SPSR_cxsf, r0 // Restore the spsr
LDR r1, [r2, #0xB0] // Load the module thread stack pointer
CPS #SYS_MODE // Switch to SYS mode
MOV sp, r1 // Set SP back to thread stack pointer
CPS #SVC_MODE // Switch back to SVC mode
#ifndef TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE
LDR r3, [r2, #0xBC] // Load the module thread stack size
STR r3, [r2, #20] // Set stack size
LDRD r0, r1, [r2, #0xB4] // Load the module thread stack start and end
STRD r0, r1, [r2, #0x0C] // Set stack start and end
#endif
LDMFD sp!, {r0-r3, r12, pc}^ // Restore the registers and return
/**************************************************************************/
/* ARM Semihosting */
/**************************************************************************/
_tx_handler_svc_arm:
/**** TODO: handle semihosting requests or ARM angel requests ****/
/* Just return. */
LDMFD sp!, {r0, r3} // Get spsr from the stack
MSR SPSR_cxsf, r0 // Restore the spsr
LDMFD sp!, {r0-r3, r12, pc}^ // Restore the registers and return
/**************************************************************************/
/* SVC 0 */
/**************************************************************************/
/* At this point we have an SVC 0: enter the scheduler. */
_tx_handler_svc_schedule:
LDMFD sp!, {r0, r3} // Get spsr from stack
MSR SPSR_cxsf, r0 // Restore spsr
LDMFD sp!, {r0-r3, r12, lr} // Restore the registers
/* This code 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. */
/* 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, #0] // 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, #0] // 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
STR r3, [r2, #0] // Setup time-slice
#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. */
CPS #SYS_MODE // Enter SYS mode
LDR sp, [r0, #8] // Switch to thread stack pointer
LDMIA sp!, {r4, r5} // Pickup the stack type and saved CPSR
CPS #SVC_MODE // Enter SVC mode
/***************************************************************************/
/* Set up MPU for module. */
LDR r1, [r0, #0x94] // Pickup module instance pointer
CMP r1, #0 // Valid module pointer?
BEQ _tx_end_mpu_update // No - skip memory protection setup
LDR r2, [r0, #0xA0] // Pickup tx_thread_module_user_mode
CMP r2, #1 // In user mode?
BNE _tx_end_mpu_update // No - skip memory protection setup
/* Is the MPU already set up for this module? */
/* Pickup the first data entry to check (txm_module_instance_mpu_registers[5]) */
LDR r2, [r1, #0xA0] // Pickup txm_module_instance_mpu_registers[5]
MOV r3, #5 // Select region 5
MCR p15, 0, r3, c6, c2, 0 // Select region 5
MRC p15, 0, r3, c6, c1, 0 // Read DRBAR into r3
CMP r2, r3 // Is module already loaded?
BEQ _tx_end_mpu_update // Yes - skip memory protection setup
/* Disable MPU before applying new regions. */
MRC p15, 0, r2, c1, c0, 0 // Read SCTLR
BIC r2, r2, #1 // Disable MPU
DSB
MCR p15, 0, r2, c1, c0, 0 // Write to SCTLR
ISB
/* Loop to load MPU registers */
MOV r3, #0 // Loop index
ADD r1, r1, #0x64 // Build address of MPU register table
_tx_mpu_loop:
LDR r2, [r1] // Pickup txm_module_mpu_region_address
MCR p15, 0, r3, c6, c2, 0 // Select region
MCR p15, 0, r2, c6, c1, 0 // Write to DRBAR
ADD r1, r1, #4 // Increment to next MPU parameter
LDR r2, [r1] // Pickup txm_module_mpu_region_size
MCR p15, 0, r2, c6, c1, 2 // Write to DRSR
ADD r1, r1, #4 // Increment to next MPU parameter
LDR r2, [r1] // Pickup txm_module_mpu_region_attributes
MCR p15, 0, r2, c6, c1, 4 // Write to DRACR
ADD r1, r1, #4 // Increment to next MPU parameter
ADD r3, r3, #1 // Increment loop index
CMP r3, #0xB // Check the limit
BLE _tx_mpu_loop // Loop if not finished
/* Enable MPU with new regions. */
MRC p15, 0, r2, c1, c0, 0 // Read SCTLR
ORR r2, r2, #1 // Enable MPU
ORR r2, r2, #0x20000 // Enable Background Region
DSB
MCR p15, 0, r2, c1, c0, 0 // Write to SCTLR
ISB
_tx_end_mpu_update:
/***************************************************************************/
CMP r4, #0 // Check for synchronous context switch
BEQ _tx_solicited_return
MSR SPSR_cxsf, r5 // Setup SPSR for return
LDR r1, [r0, #8] // Get thread SP
LDR lr, [r1, #0x40] // Get thread PC
CPS #SYS_MODE // Enter SYS mode
#ifdef __ARM_FP
LDR r2, [r0, #144] // Pickup the VFP enabled flag
CMP r2, #0 // Is the VFP enabled?
BEQ _tx_skip_interrupt_vfp_restore // No, skip VFP interrupt restore
VLDMIA sp!, {D0-D15} // Recover D0-D15
LDR r4, [sp], #4 // Pickup FPSCR
VMSR FPSCR, r4 // Restore FPSCR
CPS #SVC_MODE // Enter SVC mode
LDR lr, [r1, #0x144] // Get thread PC
CPS #SYS_MODE // Enter SYS mode
_tx_skip_interrupt_vfp_restore:
#endif
LDMIA sp!, {r0-r12, lr} // Restore registers
ADD sp, sp, #4 // Fix stack pointer
CPS #SVC_MODE // Enter SVC mode
SUBS pc, lr, #0 // Return to point of thread interrupt
_tx_solicited_return:
MOV r2, r5 // Move CPSR to scratch register
CPS #SYS_MODE // Enter SYS mode
#ifdef __ARM_FP
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
LDR r4, [sp], #4 // Pickup FPSCR
VMSR FPSCR, r4 // Restore FPSCR
_tx_skip_solicited_vfp_restore:
#endif
LDMIA sp!, {r4-r11, lr} // Restore registers
MOV r1, lr // Copy lr to r1 to preserve across mode change
CPS #SVC_MODE // Enter SVC mode
TST r1, #1 // Test LSB to see if we're returning to Thumb mode
ORRNE r2, r2, #THUMB_MASK // If so, set Thumb bit
BICEQ r2, r2, #THUMB_MASK // If not, clear Thumb bit
MSR SPSR_cxsf, r2 // Recover CPSR
MOV lr, r1 // Move r1 back to lr for a proper exception return
SUBS pc, lr, #0 // Return to thread synchronously
/**************************************************************************/
/* End __tx_svc_interrupt */
/**************************************************************************/
#ifdef __ARM_FP
.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 // Disable IRQ and FIQ interrupts
#else
CPSID i // Disable 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 // Disable IRQ and FIQ interrupts
#else
CPSID i // Disable 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

View File

@@ -0,0 +1,164 @@
/**************************************************************************/
/* */
/* 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 SYS_MODE 0x1F // SYS mode
#define THUMB_BIT 0x20 // Thumb-bit
#ifdef TX_ENABLE_FIQ_SUPPORT
#define CPSR_MASK 0xDF // Mask initial CPSR, IRQ & FIQ ints enabled
#else
#define CPSR_MASK 0x9F // Mask initial CPSR, IRQ ints enabled
#endif
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_build Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, 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 */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.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-R4 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)
MOV r3, #0 // Build initial register value
STR r3, [r2, #52] // Store initial r11
STR r3, [r2, #56] // Store initial r12
STR r3, [r2, #60] // Store initial lr
STR r1, [r2, #64] // Store initial pc
STR r3, [r2, #68] // 0 for back-trace
MRS r3, CPSR // Pickup CPSR
BIC r3, r3, #CPSR_MASK // Mask mode bits of CPSR
ORR r3, r3, #SYS_MODE // Build CPSR, SYS mode, interrupts enabled
TST r1, 1 // Test if Thumb bit is set in entry function address
ITE NE
ORRNE r3, r3, #THUMB_BIT // Yes, set the Thumb bit
BICEQ r3, r3, #THUMB_BIT // No, clear the Thumb bit
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
BX lr // Return to caller
/* } */

View File

@@ -0,0 +1,162 @@
/**************************************************************************/
/* */
/* 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_current_ptr
.global _tx_timer_time_slice
.global _tx_thread_schedule
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_thread_exit
#endif
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_system_return Cortex-R4/AC6 */
/* 6.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 */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.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 r5, =_tx_thread_current_ptr // Pickup address of current ptr
LDR r6, [r5, #0] // Pickup current thread pointer
#ifdef __ARM_FP
LDR r0, [r6, #144] // Pickup the VFP enabled flag
CMP r0, #0 // Is the VFP enabled?
BEQ _tx_skip_solicited_vfp_save // No, skip VFP solicited save
VMRS r4, FPSCR // Pickup the FPSCR
STR r4, [sp, #-4]! // Save FPSCR
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
LDR r2, =_tx_timer_time_slice // Pickup address of time slice
LDR r1, [r2, #0] // 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, [r6, #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 the current remaining time-slice. */
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; */
/* _tx_timer_time_slice = 0; */
STR r4, [r2, #0] // Clear time-slice
STR r1, [r6, #24] // Store current time-slice
/* } */
__tx_thread_dont_save_ts:
/* Clear the current thread pointer. */
/* _tx_thread_current_ptr = TX_NULL; */
STR r4, [r5, #0] // Clear current thread pointer
B _tx_thread_schedule // Jump to scheduler!
/* } */

View File

@@ -0,0 +1,193 @@
/**************************************************************************/
/* */
/* 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
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_isr_enter
#endif
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_vectored_context_save Cortex-R4/AC6 */
/* 6.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 */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.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 var
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
BX 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
BX 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
BX lr // Return to caller
/* } */
/* } */

View File

@@ -0,0 +1,257 @@
/**************************************************************************/
/* */
/* 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" */
/* 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
.global _tx_timer_expiration_process
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_timer_interrupt Cortex-R4/AC6 */
/* 6.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_timer_expiration_process Timer expiration processing */
/* _tx_thread_time_slice Time slice interrupted thread */
/* */
/* CALLED BY */
/* */
/* interrupt vector */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.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, #0] // Pickup system clock
ADD r0, r0, #1 // Increment system clock
STR r0, [r1, #0] // 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, #0] // 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, #0] // 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, #0] // 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 addr
LDR r0, [r1, #0] // Pickup current timer
LDR r2, [r0, #0] // 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, #0] // 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 wrap-around. */
/* if (_tx_timer_current_ptr == _tx_timer_list_end) */
LDR r3, =_tx_timer_list_end // Pickup addr of timer list end
LDR r2, [r3, #0] // Pickup list end
CMP r0, r2 // Are we at list end?
BNE __tx_timer_skip_wrap // No, skip wrap-around logic
/* Wrap to beginning of list. */
/* _tx_timer_current_ptr = _tx_timer_list_start; */
LDR r3, =_tx_timer_list_start // Pickup addr of timer list start
LDR r0, [r3, #0] // Set current pointer to list start
__tx_timer_skip_wrap:
STR r0, [r1, #0] // 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 addr of expired flag
LDR r2, [r3, #0] // 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 addr of other expired flag
LDR r0, [r1, #0] // 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 addr of expired flag
LDR r0, [r1, #0] // 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 addr of time-slice expired
LDR r2, [r3, #0] // 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:
BX lr // Return to caller
/* } */

View 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 */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_power_of_two_block_size Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function calculates a power of two size at or immediately above*/
/* the input size and returns it to the caller. */
/* */
/* INPUT */
/* */
/* size Block size */
/* */
/* OUTPUT */
/* */
/* calculated size Rounded up to power of two */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_alignment_adjust Adjust alignment for Cortex-R */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
ULONG _txm_power_of_two_block_size(ULONG size)
{
/* Check for 0 size. */
if(size == 0)
{
return 0;
}
/* Minimum MPU block size is 32. */
if(size <= 32)
{
return 32;
}
/* Bit twiddling trick to round to next high power of 2
(if original size is power of 2, it will return original size. Perfect!) */
size--;
size |= size >> 1;
size |= size >> 2;
size |= size >> 4;
size |= size >> 8;
size |= size >> 16;
size++;
/* Return a power of 2 size at or above the input size. */
return(size);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_alignment_adjust Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function adjusts the alignment and size of the code and data */
/* section for a given module implementation. */
/* */
/* INPUT */
/* */
/* module_preamble Pointer to module preamble */
/* code_size Size of the code area (updated) */
/* code_alignment Code area alignment (updated) */
/* data_size Size of data area (updated) */
/* data_alignment Data area alignment (updated) */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _txm_power_of_two_block_size Calculate power of two size */
/* */
/* CALLED BY */
/* */
/* Initial thread stack frame */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble,
ULONG *code_size,
ULONG *code_alignment,
ULONG *data_size,
ULONG *data_alignment)
{
ULONG local_code_size;
ULONG local_code_alignment;
ULONG local_data_size;
ULONG local_data_alignment;
ULONG code_size_accum;
ULONG data_size_accum;
/* Copy the input parameters into local variables for ease of use. */
local_code_size = *code_size;
local_code_alignment = *code_alignment;
local_data_size = *data_size;
local_data_alignment = *data_alignment;
/* Determine code block sizes. Minimize the alignment requirement.
There are 4 MPU code entries available. The following is how the code size
will be distributed:
1. 1/4 of the largest power of two that is greater than or equal to code size.
2. 1/4 of the largest power of two that is greater than or equal to code size.
3. Largest power of 2 that fits in the remaining space.
4. Smallest power of 2 that exceeds the remaining space, minimum 32. */
local_code_alignment = _txm_power_of_two_block_size(local_code_size) >> 2;
code_size_accum = local_code_alignment + local_code_alignment;
code_size_accum = code_size_accum + (_txm_power_of_two_block_size(local_code_size - code_size_accum) >> 1);
code_size_accum = code_size_accum + _txm_power_of_two_block_size(local_code_size - code_size_accum);
local_code_size = code_size_accum;
/* Determine data block sizes. Minimize the alignment requirement.
There are 4 MPU data entries available. The following is how the data size
will be distributed:
1. 1/4 of the largest power of two that is greater than or equal to data size.
2. 1/4 of the largest power of two that is greater than or equal to data size.
3. Largest power of 2 that fits in the remaining space.
4. Smallest power of 2 that exceeds the remaining space, minimum 32. */
local_data_alignment = _txm_power_of_two_block_size(local_data_size) >> 2;
data_size_accum = local_data_alignment + local_data_alignment;
data_size_accum = data_size_accum + (_txm_power_of_two_block_size(local_data_size - data_size_accum) >> 1);
data_size_accum = data_size_accum + _txm_power_of_two_block_size(local_data_size - data_size_accum);
local_data_size = data_size_accum;
/* Return all the information to the caller. */
*code_size = local_code_size;
*code_alignment = local_code_alignment;
*data_size = local_data_size;
*data_alignment = local_data_alignment;
}

View 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 */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_mutex.h"
#include "tx_queue.h"
#include "tx_thread.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_external_memory_enable Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function adds an entry in the MPU table for a shared */
/* memory space. */
/* */
/* INPUT */
/* */
/* module_instance Module instance pointer */
/* start_address Start address of memory */
/* length Length of external memory */
/* attributes Memory attributes (r/w) */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _tx_mutex_get Get protection mutex */
/* _tx_mutex_put Release protection mutex */
/* _txm_power_of_two_block_size Round length to power of two */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_external_memory_enable(TXM_MODULE_INSTANCE *module_instance,
VOID *start_address,
ULONG length,
UINT attributes)
{
ULONG block_size;
ULONG region_size;
ULONG srd_bits;
ULONG size_register;
ULONG address;
ULONG shared_index;
ULONG attributes_check = 0;
/* Determine if the module manager has been initialized. */
if (_txm_module_manager_ready != TX_TRUE)
{
/* Module manager has not been initialized. */
return(TX_NOT_AVAILABLE);
}
/* Determine if the module is valid. */
if (module_instance == TX_NULL)
{
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Get module manager protection mutex. */
_tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER);
/* Determine if the module instance is valid. */
if (module_instance -> txm_module_instance_id != TXM_MODULE_ID)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Determine if the module instance is in the loaded state. */
if (module_instance -> txm_module_instance_state != TXM_MODULE_LOADED)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return error if the module is not ready. */
return(TX_START_ERROR);
}
/* Determine if there are shared memory entries available. */
if(module_instance -> txm_module_instance_shared_memory_count >= TXM_MODULE_MPU_SHARED_ENTRIES)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* No more entries available. */
return(TX_NO_MEMORY);
}
/* Start address and length must adhere to Cortex-R MPU.
The address must align with the block size. */
block_size = _txm_power_of_two_block_size(length);
address = (ULONG) start_address;
if(address != (address & ~(block_size - 1)))
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return alignment error. */
return(TXM_MODULE_ALIGNMENT_ERROR);
}
/* At this point, we have a valid address and block size.
Set up MPU registers. */
/* Generate index into shared memory entries. */
shared_index = TXM_MODULE_MPU_SHARED_INDEX + module_instance -> txm_module_instance_shared_memory_count;
/* Save address register. */
module_instance -> txm_module_instance_mpu_registers[shared_index].txm_module_mpu_region_address = address;
/* Calculate the region size. */
region_size = (_txm_module_manager_region_size_get(block_size) << 1);
/* Calculate the subregion bits. */
srd_bits = _txm_module_manager_calculate_srd_bits(block_size, length);
/* Save size register. */
size_register = srd_bits | region_size | TXM_ENABLE_REGION;
module_instance -> txm_module_instance_mpu_registers[shared_index].txm_module_mpu_region_size = size_register;
/* Check for optional attributes. */
if(attributes & TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE)
{
attributes_check = TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT;
}
/* Save attributes register. */
module_instance -> txm_module_instance_mpu_registers[shared_index].txm_module_mpu_region_attributes = attributes_check | TXM_MODULE_MPU_SHARED_ACCESS_CONTROL;
/* Keep track of shared memory address and length in module instance. */
module_instance -> txm_module_instance_shared_memory_address[module_instance -> txm_module_instance_shared_memory_count] = address;
module_instance -> txm_module_instance_shared_memory_length[module_instance -> txm_module_instance_shared_memory_count] = length;
/* Increment counter. */
module_instance -> txm_module_instance_shared_memory_count++;
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return success. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,112 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_thread.h"
#include "txm_module.h"
/* Define the user's fault notification callback function pointer. This is
setup via the txm_module_manager_memory_fault_notify API. */
VOID (*_txm_module_manager_fault_notify)(TX_THREAD *, TXM_MODULE_INSTANCE *);
/* Define a macro that can be used to allocate global variables useful to
store information about the last fault. This macro is defined in
txm_module_port.h and is usually populated in the assembly language
fault handling prior to the code calling _txm_module_manager_memory_fault_handler. */
TXM_MODULE_MANAGER_FAULT_INFO
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_memory_fault_handler Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles a fault associated with a memory protected */
/* module. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_terminate Terminate thread */
/* */
/* CALLED BY */
/* */
/* Fault handler */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_memory_fault_handler(VOID)
{
TXM_MODULE_INSTANCE *module_instance_ptr;
TX_THREAD *thread_ptr;
/* Pickup the current thread. */
thread_ptr = _tx_thread_current_ptr;
/* Initialize the module instance pointer to NULL. */
module_instance_ptr = TX_NULL;
/* Is there a thread? */
if (thread_ptr)
{
/* Pickup the module instance. */
module_instance_ptr = thread_ptr -> tx_thread_module_instance_ptr;
/* Terminate the current thread. */
_tx_thread_terminate(_tx_thread_current_ptr);
}
/* Determine if there is a user memory fault notification callback. */
if (_txm_module_manager_fault_notify)
{
/* Yes, call the user's notification memory fault callback. */
(_txm_module_manager_fault_notify)(thread_ptr, module_instance_ptr);
}
}

View File

@@ -0,0 +1,85 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_thread.h"
#include "txm_module.h"
/* Define the external user's fault notification callback function pointer. This is
setup via the txm_module_manager_memory_fault_notify API. */
extern VOID (*_txm_module_manager_fault_notify)(TX_THREAD *, TXM_MODULE_INSTANCE *);
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_memory_fault_notify Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function registers an application callback when/if a memory */
/* fault occurs. The supplied thread is automatically terminated, but */
/* any other threads in the same module may still execute. */
/* */
/* INPUT */
/* */
/* notify_function Memory fault notification */
/* function, NULL disables. */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_memory_fault_notify(VOID (*notify_function)(TX_THREAD *, TXM_MODULE_INSTANCE *))
{
/* Setup notification function. */
_txm_module_manager_fault_notify = notify_function;
/* Return success. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,547 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_region_size_get Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function converts the region size in bytes to the block size */
/* for the Cortex-R4 MPU specification. */
/* */
/* INPUT */
/* */
/* block_size Size of the block in bytes */
/* */
/* OUTPUT */
/* */
/* MPU size specification */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_mm_register_setup */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
ULONG _txm_module_manager_region_size_get(ULONG block_size)
{
ULONG return_value;
/* Process relative to the input block size. */
if (block_size == 32)
{
return_value = 0x04;
}
else if (block_size == 64)
{
return_value = 0x05;
}
else if (block_size == 128)
{
return_value = 0x06;
}
else if (block_size == 256)
{
return_value = 0x07;
}
else if (block_size == 512)
{
return_value = 0x08;
}
else if (block_size == 1024)
{
return_value = 0x09;
}
else if (block_size == 2048)
{
return_value = 0x0A;
}
else if (block_size == 4096)
{
return_value = 0x0B;
}
else if (block_size == 8192)
{
return_value = 0x0C;
}
else if (block_size == 16384)
{
return_value = 0x0D;
}
else if (block_size == 32768)
{
return_value = 0x0E;
}
else if (block_size == 65536)
{
return_value = 0x0F;
}
else if (block_size == 131072)
{
return_value = 0x10;
}
else if (block_size == 262144)
{
return_value = 0x11;
}
else if (block_size == 524288)
{
return_value = 0x12;
}
else if (block_size == 1048576)
{
return_value = 0x13;
}
else if (block_size == 2097152)
{
return_value = 0x14;
}
else
{
/* Max 4MB MPU pages for modules. */
return_value = 0x15;
}
return(return_value);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_calculate_srd_bits Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function calculates the SRD bits that need to be set to */
/* protect "length" bytes in a block. */
/* */
/* INPUT */
/* */
/* block_size Size of the block in bytes */
/* length Actual length in bytes */
/* */
/* OUTPUT */
/* */
/* SRD bits to be OR'ed with region attribute register. */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_mm_register_setup */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
ULONG _txm_module_manager_calculate_srd_bits(ULONG block_size, ULONG length)
{
ULONG srd_bits = 0;
UINT srd_bit_index;
/* length is smaller than block_size, set SRD bits if block_size is 256 or more. */
if((block_size >= 256) && (length < block_size))
{
/* Divide block_size by 8 by shifting right 3. Result is size of subregion. */
block_size = block_size >> 3;
/* Set SRD index into attribute register. */
srd_bit_index = 8;
/* If subregion overlaps length, move to the next subregion. */
while(length > block_size)
{
length = length - block_size;
srd_bit_index++;
}
/* Check for a portion of code remaining. */
if(length)
{
srd_bit_index++;
}
/* Set unused subregion bits. */
while(srd_bit_index < 16)
{
srd_bits = srd_bits | (0x1 << srd_bit_index);
srd_bit_index++;
}
}
return(srd_bits);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_register_setup Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sets up the MPU register definitions based on the */
/* module's memory characteristics. */
/* MPU layout for the Cortex-R4: */
/* Entry Description */
/* 0 Kernel mode entry */
/* 1 Module code region */
/* 2 Module code region */
/* 3 Module code region */
/* 4 Module code region */
/* 5 Module data region */
/* 6 Module data region */
/* 7 Module data region */
/* 8 Module data region */
/* 9 Module shared memory region */
/* 10 Module shared memory region */
/* 11 Module shared memory region */
/* */
/* */
/* INPUT */
/* */
/* module_instance Pointer to module instance */
/* */
/* OUTPUT */
/* */
/* MPU specifications for module in module_instance */
/* */
/* CALLS */
/* */
/* _txm_module_manager_region_size_get */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_thread_create */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
{
ULONG code_address;
ULONG code_size;
ULONG data_address;
ULONG data_size;
ULONG start_stop_stack_size;
ULONG callback_stack_size;
ULONG block_size;
ULONG base_address_register;
ULONG size_register;
ULONG region_size;
ULONG srd_bits = 0;
UINT mpu_table_index;
UINT i;
/* Setup the first region for kernel mode entry. */
/* Set address register to user mode entry function address, which is guaranteed to be at least 32-byte aligned. */
module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MPU_KERNEL_ENTRY_INDEX].txm_module_mpu_region_address = (ULONG) _txm_module_manager_user_mode_entry;
/* Set the size (32 bytes) and enable bit. */
module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MPU_KERNEL_ENTRY_INDEX].txm_module_mpu_region_size = (_txm_module_manager_region_size_get(32) << 1) | TXM_ENABLE_REGION;
/* Set attributes. */
module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MPU_KERNEL_ENTRY_INDEX].txm_module_mpu_region_attributes = TXM_MODULE_MPU_CODE_ACCESS_CONTROL;
/* End of kernel mode entry setup. */
/* Setup code protection. */
/* Initialize the MPU table index. */
mpu_table_index = 1;
/* Pickup code starting address and actual size. */
code_address = (ULONG) module_instance -> txm_module_instance_code_start;
code_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_code_size;
/* Determine code block sizes. Minimize the alignment requirement.
There are 4 MPU code entries available. The following is how the code size
will be distributed:
1. 1/4 of the largest power of two that is greater than or equal to code size.
2. 1/4 of the largest power of two that is greater than or equal to code size.
3. Largest power of 2 that fits in the remaining space.
4. Smallest power of 2 that exceeds the remaining space, minimum 32. */
/* Now loop through to setup MPU protection for the code area. */
for (i = 0; i < TXM_MODULE_MPU_CODE_ENTRIES; i++)
{
/* First two MPU blocks are 1/4 of the largest power of two
that is greater than or equal to code size. */
if (i < 2)
{
block_size = _txm_power_of_two_block_size(code_size) >> 2;
}
/* Third MPU block is the largest power of 2 that fits in the remaining space. */
else if (i == 2)
{
/* Subtract (block_size*2) from code_size to calculate remaining space. */
code_size = code_size - (block_size << 1);
block_size = _txm_power_of_two_block_size(code_size) >> 1;
}
/* Last MPU block is the smallest power of 2 that exceeds the remaining space, minimum 32. */
else
{
/* Calculate remaining space. */
code_size = code_size - block_size;
block_size = _txm_power_of_two_block_size(code_size);
srd_bits = _txm_module_manager_calculate_srd_bits(block_size, code_size);
}
/* Build the base address register. */
base_address_register = (code_address & ~(block_size - 1));
/* Calculate the region size information. */
region_size = (_txm_module_manager_region_size_get(block_size) << 1);
/* Build the size register. */
size_register = srd_bits | region_size | TXM_ENABLE_REGION;
/* Setup the MPU address, size, and attribute registers. */
module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = base_address_register;
module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_size = size_register;
module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_attributes = TXM_MODULE_MPU_CODE_ACCESS_CONTROL;
/* Adjust the code address. */
code_address = code_address + block_size;
/* Increment MPU table index. */
mpu_table_index++;
}
/* End of code protection. */
/* Setup data protection. */
/* Reset SRD bitfield. */
srd_bits = 0;
/* Pickup data starting address and actual size. */
data_address = (ULONG) module_instance -> txm_module_instance_data_start;
/* Adjust the size of the module elements to be aligned to the default alignment. We do this
so that when we partition the allocated memory, we can simply place these regions right beside
each other without having to align their pointers. Note this only works when they all have
the same alignment. */
data_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_data_size;
start_stop_stack_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_start_stop_stack_size;
callback_stack_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_callback_stack_size;
data_size = ((data_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT;
start_stop_stack_size = ((start_stop_stack_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT;
callback_stack_size = ((callback_stack_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT;
/* Update the data size to include thread stacks. */
data_size = data_size + start_stop_stack_size + callback_stack_size;
/* Determine data block sizes. Minimize the alignment requirement.
There are 4 MPU data entries available. The following is how the data size
will be distributed:
1. 1/4 of the largest power of two that is greater than or equal to data size.
2. 1/4 of the largest power of two that is greater than or equal to data size.
3. Largest power of 2 that fits in the remaining space.
4. Smallest power of 2 that exceeds the remaining space, minimum 32. */
/* Now loop through to setup MPU protection for the data area. */
for (i = 0; i < TXM_MODULE_MPU_DATA_ENTRIES; i++)
{
/* First two MPU blocks are 1/4 of the largest power of two
that is greater than or equal to data size. */
if (i < 2)
{
block_size = _txm_power_of_two_block_size(data_size) >> 2;
}
/* Third MPU block is the largest power of 2 that fits in the remaining space. */
else if (i == 2)
{
/* Subtract (block_size*2) from data_size to calculate remaining space. */
data_size = data_size - (block_size << 1);
block_size = _txm_power_of_two_block_size(data_size) >> 1;
}
/* Last MPU block is the smallest power of 2 that exceeds the remaining space, minimum 32. */
else
{
/* Calculate remaining space. */
data_size = data_size - block_size;
block_size = _txm_power_of_two_block_size(data_size);
srd_bits = _txm_module_manager_calculate_srd_bits(block_size, data_size);
}
/* Build the base address register. */
base_address_register = (data_address & ~(block_size - 1));
/* Calculate the region size information. */
region_size = (_txm_module_manager_region_size_get(block_size) << 1);
/* Build the size register. */
size_register = srd_bits | region_size | TXM_ENABLE_REGION;
/* Setup the MPU address, size, and attribute registers. */
module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = base_address_register;
module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_size = size_register;
module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_attributes = TXM_MODULE_MPU_DATA_ACCESS_CONTROL;
/* Adjust the data address. */
data_address = data_address + block_size;
/* Increment MPU table index. */
mpu_table_index++;
}
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_inside_data_check Cortex-R4/MPU/ARM */
/* 6.1.6 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function checks if the specified object is inside shared */
/* memory. */
/* */
/* INPUT */
/* */
/* module_instance Pointer to module instance */
/* obj_ptr Pointer to the object */
/* obj_size Size of the object */
/* */
/* OUTPUT */
/* */
/* Whether the object is inside the shared memory region. */
/* */
/* CALLS */
/* */
/* N/A */
/* */
/* CALLED BY */
/* */
/* Module dispatch check functions */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 04-02-2021 Scott Larson Modified comments, added */
/* check for overflow, */
/* resulting in version 6.1.6 */
/* */
/**************************************************************************/
UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE obj_ptr, UINT obj_size)
{
UINT shared_memory_index;
UINT num_shared_memory_mpu_entries;
ALIGN_TYPE shared_memory_address_start;
ALIGN_TYPE shared_memory_address_end;
/* Check for overflow. */
if ((obj_ptr) > ((obj_ptr) + (obj_size)))
{
return(TX_FALSE);
}
/* Check if the object is inside the module data. */
if ((obj_ptr >= (ALIGN_TYPE) module_instance -> txm_module_instance_data_start) &&
((obj_ptr + obj_size) <= ((ALIGN_TYPE) module_instance -> txm_module_instance_data_end + 1)))
{
return(TX_TRUE);
}
/* Check if the object is inside the shared memory. */
num_shared_memory_mpu_entries = module_instance -> txm_module_instance_shared_memory_count;
for (shared_memory_index = 0; shared_memory_index < num_shared_memory_mpu_entries; shared_memory_index++)
{
shared_memory_address_start = (ALIGN_TYPE) module_instance -> txm_module_instance_shared_memory_address[shared_memory_index];
shared_memory_address_end = shared_memory_address_start + module_instance -> txm_module_instance_shared_memory_length[shared_memory_index];
if ((obj_ptr >= (ALIGN_TYPE) shared_memory_address_start) &&
((obj_ptr + obj_size) <= (ALIGN_TYPE) shared_memory_address_end))
{
return(TX_TRUE);
}
}
return(TX_FALSE);
}

View File

@@ -0,0 +1,146 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define THUMB_MASK 0x20 // THUMB bit
#define USR_MODE 0x10 // USR mode
#define SYS_MODE 0x1F // SYS mode
#define CPSR_MASK 0xBF // Mask initial CPSR, IRQ ints enabled
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_thread_stack_build Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, 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 */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _txm_module_manager_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(TX_THREAD *, TXM_MODULE_INSTANCE *))
{ */
.text
.global _txm_module_manager_thread_stack_build
.type _txm_module_manager_thread_stack_build, "function"
_txm_module_manager_thread_stack_build:
/* Build a fake interrupt frame. The form of the fake interrupt stack
on the Cortex-R4 should look like the following after it is built:
Stack Top: 1 Interrupt stack frame type
CPSR Initial value for CPSR
r0 Initial value for r0
r1 Initial value for r1
r2 Initial value for r2
r3 Initial value for r3
r4 Initial value for r4
r5 Initial value for r5
r6 Initial value for r6
r7 Initial value for r7
r8 Initial value for r8
r9 Initial value for r9
r10 Initial value for r10
r11 Initial value for r11
r12 Initial value for r12
lr Initial value for lr (r14)
pc Initial value for pc (r15)
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
STR r0, [r2, #8] // Store initial r0 (thread pointer)
LDR r3, [r0, #8] // Pickup thread info pointer (it's in the stack pointer location right now)
STR r3, [r2, #12] // Store initial r1
LDR r3, [r3, #8] // Pickup data base register
STR r3, [r2, #44] // Store initial r9
MOV r3, #0 // Build initial register value
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
LDR r3, [r0, #12] // Pickup stack starting address
STR r3, [r2, #48] // Store initial r10 (sl)
MOV r3, #0 // Build initial register value
STR r3, [r2, #52] // Store initial r11
STR r3, [r2, #56] // Store initial r12
STR r3, [r2, #60] // Store initial lr
STR r1, [r2, #64] // Store initial pc
STR r3, [r2, #68] // 0 for back-trace
MRS r3, CPSR // Pickup CPSR
BIC r3, r3, #CPSR_MASK // Mask mode bits of CPSR
TST r1, #1 // Test if THUMB bit set in initial PC
ORRNE r3, r3, #THUMB_MASK // Set T bit if set
LDR r1, [r0, #156] // Load tx_thread_module_user_mode
TST r1, #1 // Test if the user mode flag is set
ORREQ r3, r3, #SYS_MODE // Flag not set: Build CPSR, SYS mode, IRQ enabled
ORRNE r3, r3, #USR_MODE // Flag set: Build CPSR, USR mode, IRQ 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
BX lr // Return to caller
/* } */

View File

@@ -0,0 +1,86 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Manager */
/** */
/**************************************************************************/
/**************************************************************************/
.global _txm_module_manager_kernel_dispatch
.global _txm_system_mode_enter
.global _txm_system_mode_exit
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_user_mode_entry Cortex-R4/MPU/ARM */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function allows modules to enter kernel mode. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* SVC 1 Enter kernel mode */
/* SVC 2 Exit kernel mode */
/* */
/* CALLED BY */
/* */
/* Modules in user mode */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
.text
.align 12
.eabi_attribute Tag_ABI_align_preserved, 1
.global _txm_module_manager_user_mode_entry
.type _txm_module_manager_user_mode_entry, "function"
_txm_module_manager_user_mode_entry:
_txm_system_mode_enter:
SVC 1 // Get out of user mode.
_txm_module_priv:
/* At this point, we are in system mode.
Save LR (and r3 for 8 byte aligned stack) and call the kernel dispatch function. */
PUSH {r3, lr}
BL _txm_module_manager_kernel_dispatch
POP {r3, lr}
_txm_system_mode_exit:
/* Trap to restore user mode while inside of ThreadX. */
SVC 2
BX lr // Return to the caller.
NOP
NOP

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<workspace>
<project>
<path>$WS_DIR$\sample_threadx.ewp</path>
</project>
<project>
<path>$WS_DIR$\sample_threadx_module.ewp</path>
</project>
<project>
<path>$WS_DIR$\sample_threadx_module_manager.ewp</path>
</project>
<project>
<path>$WS_DIR$\tx.ewp</path>
</project>
<project>
<path>$WS_DIR$\txm.ewp</path>
</project>
<batchBuild />
</workspace>

View File

@@ -0,0 +1,177 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Part one of the system initialization code,
;; contains low-level
;; initialization.
;;
;; Copyright 2007-2017 IAR Systems AB.
;;
;; $Revision: 112610 $
;;
MODULE ?cstartup
;; Forward declaration of sections.
SECTION IRQ_STACK:DATA:NOROOT(3)
SECTION FIQ_STACK:DATA:NOROOT(3)
SECTION CSTACK:DATA:NOROOT(3)
SECTION SVC_STACK:DATA:NOROOT(3)
SECTION ABT_STACK:DATA:NOROOT(3)
;
; The module in this file are included in the libraries, and may be
; replaced by any user-defined modules that define the PUBLIC symbol
; __iar_program_start or a user defined start symbol.
;
; To override the cstartup defined in the library, simply add your
; modified version to the workbench project.
SECTION .intvec:CODE:NOROOT(2)
PUBLIC __vector
PUBLIC __iar_program_start
EXTERN Undefined_Handler
EXTERN SWI_Handler
EXTERN Prefetch_Handler
EXTERN Abort_Handler
EXTERN IRQ_Handler
EXTERN FIQ_Handler
DATA
__iar_init$$done: ; The vector table is not needed
; until after copy initialization is done
__vector: ; Make this a DATA label, so that stack usage
; analysis doesn't consider it an uncalled fun
ARM
; All default exception handlers (except reset) are
; defined as weak symbol definitions.
; If a handler is defined by the application it will take precedence.
LDR PC,Reset_Addr ; Reset
LDR PC,Undefined_Addr ; Undefined instructions
LDR PC,SWI_Addr ; Software interrupt (SWI/SVC)
LDR PC,Prefetch_Addr ; Prefetch abort
LDR PC,Abort_Addr ; Data abort
DCD 0 ; RESERVED
LDR PC,IRQ_Addr ; IRQ
LDR PC,FIQ_Addr ; FIQ
DATA
Reset_Addr: DCD __iar_program_start
Undefined_Addr: DCD Undefined_Handler
SWI_Addr: DCD SWI_Handler
Prefetch_Addr: DCD Prefetch_Handler
Abort_Addr: DCD Abort_Handler
IRQ_Addr: DCD IRQ_Handler
FIQ_Addr: DCD FIQ_Handler
; --------------------------------------------------
; ?cstartup -- low-level system initialization code.
;
; After a reset execution starts here, the mode is ARM, supervisor
; with interrupts disabled.
;
SECTION .text:CODE:NOROOT(2)
EXTERN __cmain
REQUIRE __vector
EXTWEAK __iar_init_core
EXTWEAK __iar_init_vfp
ARM
__iar_program_start:
?cstartup:
;
; Add initialization needed before setup of stackpointers here.
;
;
; Initialize the stack pointers.
; The pattern below can be used for any of the exception stacks:
; FIQ, IRQ, SVC, ABT, UND, SYS.
; The USR mode uses the same stack as SYS.
; The stack segments must be defined in the linker command file,
; and be declared above.
;
; --------------------
; Mode, correspords to bits 0-5 in CPSR
#define MODE_MSK 0x1F ; Bit mask for mode bits in CPSR
#define USR_MODE 0x10 ; User mode
#define FIQ_MODE 0x11 ; Fast Interrupt Request mode
#define IRQ_MODE 0x12 ; Interrupt Request mode
#define SVC_MODE 0x13 ; Supervisor mode
#define ABT_MODE 0x17 ; Abort mode
#define UND_MODE 0x1B ; Undefined Instruction mode
#define SYS_MODE 0x1F ; System mode
MRS r0, cpsr ; Original PSR value
;; Set up the interrupt stack pointer.
BIC r0, r0, #MODE_MSK ; Clear the mode bits
ORR r0, r0, #IRQ_MODE ; Set IRQ mode bits
MSR cpsr_c, r0 ; Change the mode
LDR r1, =SFE(IRQ_STACK) ; End of IRQ_STACK
BIC sp,r1,#0x7 ; Make sure SP is 8 aligned
;; Set up the fast interrupt stack pointer.
BIC r0, r0, #MODE_MSK ; Clear the mode bits
ORR r0, r0, #FIQ_MODE ; Set FIR mode bits
MSR cpsr_c, r0 ; Change the mode
LDR r1, =SFE(FIQ_STACK) ; End of FIQ_STACK
BIC sp,r1,#0x7 ; Make sure SP is 8 aligned
;; Set up the SVC stack pointer.
CPS #SVC_MODE
LDR r1, =SFE(SVC_STACK) ; End of SVC_STACK
BIC sp,r1,#0x7 ; Make sure SP is 8 aligned
;; Set up the abort stack pointer.
CPS #ABT_MODE
LDR r1, =SFE(ABT_STACK) ; End of ABT_STACK
BIC sp,r1,#0x7 ; Make sure SP is 8 aligned
;; Set up the normal stack pointer.
BIC r0 ,r0, #MODE_MSK ; Clear the mode bits
ORR r0 ,r0, #SYS_MODE ; Set System mode bits
MSR cpsr_c, r0 ; Change the mode
LDR r1, =SFE(CSTACK) ; End of CSTACK
BIC sp,r1,#0x7 ; Make sure SP is 8 aligned
;; Turn on core features assumed to be enabled.
FUNCALL __iar_program_start, __iar_init_core
BL __iar_init_core
;; Initialize VFP (if needed).
FUNCALL __iar_program_start, __iar_init_vfp
BL __iar_init_vfp
;;;
;;; Add more initialization here
;;;
;;; Continue to __cmain for C-level initialization.
FUNCALL __iar_program_start, __cmain
B __cmain
END

View File

@@ -0,0 +1,376 @@
/* 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 byte pool memory. */
UCHAR byte_pool_memory[DEMO_BYTE_POOL_SIZE];
/* 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", byte_pool_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;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,49 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00000040;
define symbol __ICFEDIT_region_ROM_end__ = 0x0013FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x08000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x0802FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x200;
define symbol __ICFEDIT_size_svcstack__ = 0x100;
define symbol __ICFEDIT_size_irqstack__ = 0x100;
define symbol __ICFEDIT_size_fiqstack__ = 0x100;
define symbol __ICFEDIT_size_undstack__ = 0x100;
define symbol __ICFEDIT_size_abtstack__ = 0x100;
define symbol __ICFEDIT_size_heap__ = 0x200;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define symbol __region_DRAM_start__ = 0x80000000;
define symbol __region_DRAM_end__ = 0x807FFFFF;
define region DRAM_region = mem:[from __region_DRAM_start__ to __region_DRAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block SVC_STACK with alignment = 8, size = __ICFEDIT_size_svcstack__ { };
define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { };
define block FIQ_STACK with alignment = 8, size = __ICFEDIT_size_fiqstack__ { };
define block UND_STACK with alignment = 8, size = __ICFEDIT_size_undstack__ { };
define block ABT_STACK with alignment = 8, size = __ICFEDIT_size_abtstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK,
block UND_STACK, block ABT_STACK, block HEAP};
place in DRAM_region { section DRAM };
place in RAM_region { last section FREE_MEM};

View File

@@ -0,0 +1,425 @@
/* This is a small demo of the high-performance ThreadX kernel running as a module. It includes
examples of eight threads of different priorities, using a message queue, semaphore, mutex,
event flags group, byte pool, and block pool. */
/* Specify that this is a module! */
#define TXM_MODULE
/* Include the ThreadX module definitions. */
#include "txm_module.h"
/* Define constants. */
#define DEMO_STACK_SIZE 1024
#define DEMO_BYTE_POOL_SIZE 9120
#define DEMO_BLOCK_POOL_SIZE 100
#define DEMO_QUEUE_SIZE 100
/* Define the pool space in the bss section of the module. ULONG is used to
get the word alignment. */
ULONG demo_module_pool_space[DEMO_BYTE_POOL_SIZE / 4];
/* 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;
ULONG semaphore_0_puts;
ULONG event_0_sets;
ULONG queue_0_sends;
/* 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);
void semaphore_0_notify(TX_SEMAPHORE *semaphore_ptr)
{
if (semaphore_ptr == semaphore_0)
semaphore_0_puts++;
}
void event_0_notify(TX_EVENT_FLAGS_GROUP *event_flag_group_ptr)
{
if (event_flag_group_ptr == event_flags_0)
event_0_sets++;
}
void queue_0_notify(TX_QUEUE *queue_ptr)
{
if (queue_ptr == queue_0)
queue_0_sends++;
}
/* Define the module start function. */
void demo_module_start(ULONG id)
{
CHAR *pointer;
/* Allocate all the objects. In MPU mode, modules cannot allocate control blocks within
their own memory area so they cannot corrupt the resident portion of ThreadX by overwriting
the control block(s). */
txm_module_object_allocate((void*)&thread_0, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&thread_1, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&thread_2, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&thread_3, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&thread_4, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&thread_5, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&thread_6, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&thread_7, sizeof(TX_THREAD));
txm_module_object_allocate((void*)&queue_0, sizeof(TX_QUEUE));
txm_module_object_allocate((void*)&semaphore_0, sizeof(TX_SEMAPHORE));
txm_module_object_allocate((void*)&mutex_0, sizeof(TX_MUTEX));
txm_module_object_allocate((void*)&event_flags_0, sizeof(TX_EVENT_FLAGS_GROUP));
txm_module_object_allocate((void*)&byte_pool_0, sizeof(TX_BYTE_POOL));
txm_module_object_allocate((void*)&block_pool_0, sizeof(TX_BLOCK_POOL));
/* Create a byte memory pool from which to allocate the thread stacks. */
tx_byte_pool_create(byte_pool_0, "module byte pool 0", demo_module_pool_space, 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
tx_queue_send_notify(queue_0, queue_0_notify);
/* Create the semaphore used by threads 3 and 4. */
tx_semaphore_create(semaphore_0, "module semaphore 0", 1);
tx_semaphore_put_notify(semaphore_0, semaphore_0_notify);
/* Create the event flags group used by threads 1 and 5. */
tx_event_flags_create(event_flags_0, "module event flags 0");
tx_event_flags_set_notify(event_flags_0, event_0_notify);
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
tx_mutex_create(mutex_0, "module 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, "module 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;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,44 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
/*-Specials-*/
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00100000;
define symbol __ICFEDIT_region_ROM_end__ = 0x0013FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x08000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x0800FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0;
define symbol __ICFEDIT_size_svcstack__ = 0;
define symbol __ICFEDIT_size_irqstack__ = 0;
define symbol __ICFEDIT_size_fiqstack__ = 0;
define symbol __ICFEDIT_size_undstack__ = 0;
define symbol __ICFEDIT_size_abtstack__ = 0;
define symbol __ICFEDIT_size_heap__ = 0x100;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
define movable block ROPI with alignment = 4, fixed order
{
ro object txm_module_preamble.o,
ro,
ro data
};
define movable block RWPI with alignment = 8, fixed order, static base
{
rw,
block HEAP
};
place in ROM_region { block ROPI };
place in RAM_region { block RWPI };

View File

@@ -0,0 +1,104 @@
/* Small demonstration of the ThreadX module manager. */
#include "tx_api.h"
#include "txm_module.h"
#define DEMO_STACK_SIZE 1024
/* Define the ThreadX object control blocks... */
TX_THREAD module_manager;
TXM_MODULE_INSTANCE my_module;
UCHAR manager_stack[1024];
/* Define the object pool area. */
UCHAR object_memory[8192];
/* Define the count of memory faults. */
ULONG memory_faults;
/* Define thread prototypes. */
void module_manager_entry(ULONG thread_input);
/* Define fault handler. */
VOID module_fault_handler(TX_THREAD *thread, TXM_MODULE_INSTANCE *module)
{
/* Just increment the fault counter. */
memory_faults++;
}
/* 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)
{
tx_thread_create(&module_manager, "Module Manager Thread", module_manager_entry, 0,
manager_stack, DEMO_STACK_SIZE,
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
}
/* Define the test threads. */
void module_manager_entry(ULONG thread_input)
{
/* Initialize the module manager. */
txm_module_manager_initialize((VOID *) 0x08020000, 0x10000);
txm_module_manager_object_pool_create(object_memory, sizeof(object_memory));
/* Register a fault handler. */
txm_module_manager_memory_fault_notify(module_fault_handler);
/* Load the module that is already there, in this example it is placed there by the multiple image download. */
txm_module_manager_in_place_load(&my_module, "my module", (VOID *) 0x00100000);
/* Enable 128 byte read/write shared memory region at 0x08025000. */
txm_module_manager_external_memory_enable(&my_module, (void *) 0x08025000, 128, TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE);
/* Start the module. */
txm_module_manager_start(&my_module);
/* Sleep for a while.... */
tx_thread_sleep(300);
/* Stop the module. */
txm_module_manager_stop(&my_module);
/* Unload the module. */
txm_module_manager_unload(&my_module);
/* Load the module that is already there. */
txm_module_manager_in_place_load(&my_module, "my module", (VOID *) 0x00100000);
/* Start the module again. */
txm_module_manager_start(&my_module);
/* Now just spin... */
while(1)
{
tx_thread_sleep(100);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,49 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00000040;
define symbol __ICFEDIT_region_ROM_end__ = 0x000FFFFF; //Module in 0x00100000-0x0013FFFF
define symbol __ICFEDIT_region_RAM_start__ = 0x08000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x0801FFFF; //Module in 0x08020000-0x0802FFFF
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x200;
define symbol __ICFEDIT_size_svcstack__ = 0x100;
define symbol __ICFEDIT_size_irqstack__ = 0x100;
define symbol __ICFEDIT_size_fiqstack__ = 0x100;
define symbol __ICFEDIT_size_undstack__ = 0x100;
define symbol __ICFEDIT_size_abtstack__ = 0x100;
define symbol __ICFEDIT_size_heap__ = 0x200;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define symbol __region_DRAM_start__ = 0x80000000;
define symbol __region_DRAM_end__ = 0x807FFFFF;
define region DRAM_region = mem:[from __region_DRAM_start__ to __region_DRAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block SVC_STACK with alignment = 8, size = __ICFEDIT_size_svcstack__ { };
define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { };
define block FIQ_STACK with alignment = 8, size = __ICFEDIT_size_fiqstack__ { };
define block UND_STACK with alignment = 8, size = __ICFEDIT_size_undstack__ { };
define block ABT_STACK with alignment = 8, size = __ICFEDIT_size_abtstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK,
block UND_STACK, block ABT_STACK, block HEAP};
place in DRAM_region { section DRAM };
place in RAM_region { last section FREE_MEM};

View File

@@ -0,0 +1,100 @@
<?xml version="1.0"?>
<settings>
<Stack>
<FillEnabled>0</FillEnabled>
<OverflowWarningsEnabled>1</OverflowWarningsEnabled>
<WarningThreshold>90</WarningThreshold>
<SpWarningsEnabled>1</SpWarningsEnabled>
<WarnLogOnly>1</WarnLogOnly>
<UseTrigger>1</UseTrigger>
<TriggerName>main</TriggerName>
<LimitSize>0</LimitSize>
<ByteLimit>50</ByteLimit>
</Stack>
<Trace1>
<Enabled>0</Enabled>
<ShowSource>1</ShowSource>
</Trace1>
<DebugChecksum>
<Checksum>157308190</Checksum>
</DebugChecksum>
<Disassembly>
<InstrCount>0</InstrCount>
<MixedMode>1</MixedMode>
</Disassembly>
<CodeCoverage>
<Enabled>0</Enabled>
<ShowSource>0</ShowSource>
<HideCovered>0</HideCovered>
</CodeCoverage>
<DriverProfiling>
<Enabled>0</Enabled>
<Mode>1</Mode>
<Graph>0</Graph>
<Symbiont>0</Symbiont>
</DriverProfiling>
<CallStackLog>
<Enabled>0</Enabled>
</CallStackLog>
<CallStackStripe>
<ShowTiming>1</ShowTiming>
</CallStackStripe>
<Exceptions>
<StopOnUncaught>_ 0</StopOnUncaught>
<StopOnThrow>_ 0</StopOnThrow>
</Exceptions>
<TermIOLog>
<LoggingEnabled>_ 0</LoggingEnabled>
<LogFile>_ ""</LogFile>
</TermIOLog>
<LogFile>
<LoggingEnabled>_ 0</LoggingEnabled>
<LogFile>_ ""</LogFile>
<Category>_ 0</Category>
</LogFile>
<CallStack>
<ShowArgs>0</ShowArgs>
</CallStack>
<InterruptLog>
<LogEnabled>0</LogEnabled>
<GraphEnabled>0</GraphEnabled>
<ShowTimeLog>1</ShowTimeLog>
<SumEnabled>0</SumEnabled>
<ShowTimeSum>1</ShowTimeSum>
<SumSortOrder>0</SumSortOrder>
</InterruptLog>
<DataLog>
<LogEnabled>0</LogEnabled>
<GraphEnabled>0</GraphEnabled>
<ShowTimeLog>1</ShowTimeLog>
<SumEnabled>0</SumEnabled>
<ShowTimeSum>1</ShowTimeSum>
</DataLog>
<DisassembleMode>
<mode>0</mode>
</DisassembleMode>
<Breakpoints2>
<Count>0</Count>
</Breakpoints2>
<Interrupts>
<Enabled>1</Enabled>
<Irq0>_ 0 10000 0 10000 1 0 0 100 0 1 "IRQ 1 0x18 CPSR.I"</Irq0>
<Count>1</Count>
</Interrupts>
<MemConfig>
<Base>1</Base>
<Manual>0</Manual>
<Ddf>1</Ddf>
<TypeViol>0</TypeViol>
<Stop>1</Stop>
</MemConfig>
<Aliases>
<Count>0</Count>
<SuppressDialog>0</SuppressDialog>
</Aliases>
<Simulator>
<Freq>10000000</Freq>
<FreqHi>0</FreqHi>
<MultiCoreRunAll>1</MultiCoreRunAll>
</Simulator>
</settings>

View File

@@ -0,0 +1,100 @@
<?xml version="1.0"?>
<settings>
<DebugChecksum>
<Checksum>1819642867</Checksum>
</DebugChecksum>
<Stack>
<FillEnabled>0</FillEnabled>
<OverflowWarningsEnabled>1</OverflowWarningsEnabled>
<WarningThreshold>90</WarningThreshold>
<SpWarningsEnabled>1</SpWarningsEnabled>
<WarnLogOnly>1</WarnLogOnly>
<UseTrigger>1</UseTrigger>
<TriggerName>main</TriggerName>
<LimitSize>0</LimitSize>
<ByteLimit>50</ByteLimit>
</Stack>
<Disassembly>
<InstrCount>0</InstrCount>
<MixedMode>1</MixedMode>
</Disassembly>
<CodeCoverage>
<Enabled>0</Enabled>
<ShowSource>0</ShowSource>
<HideCovered>0</HideCovered>
</CodeCoverage>
<Trace1>
<Enabled>0</Enabled>
<ShowSource>1</ShowSource>
</Trace1>
<Exceptions>
<StopOnUncaught>_ 0</StopOnUncaught>
<StopOnThrow>_ 0</StopOnThrow>
</Exceptions>
<CallStack>
<ShowArgs>0</ShowArgs>
</CallStack>
<DriverProfiling>
<Enabled>0</Enabled>
<Mode>1</Mode>
<Graph>0</Graph>
<Symbiont>0</Symbiont>
</DriverProfiling>
<CallStackLog>
<Enabled>0</Enabled>
</CallStackLog>
<CallStackStripe>
<ShowTiming>1</ShowTiming>
</CallStackStripe>
<TermIOLog>
<LoggingEnabled>_ 0</LoggingEnabled>
<LogFile>_ ""</LogFile>
</TermIOLog>
<LogFile>
<LoggingEnabled>_ 0</LoggingEnabled>
<LogFile>_ ""</LogFile>
<Category>_ 0</Category>
</LogFile>
<InterruptLog>
<LogEnabled>0</LogEnabled>
<GraphEnabled>0</GraphEnabled>
<ShowTimeLog>1</ShowTimeLog>
<SumEnabled>0</SumEnabled>
<ShowTimeSum>1</ShowTimeSum>
<SumSortOrder>0</SumSortOrder>
</InterruptLog>
<DataLog>
<LogEnabled>0</LogEnabled>
<GraphEnabled>0</GraphEnabled>
<ShowTimeLog>1</ShowTimeLog>
<SumEnabled>0</SumEnabled>
<ShowTimeSum>1</ShowTimeSum>
</DataLog>
<DisassembleMode>
<mode>0</mode>
</DisassembleMode>
<Breakpoints2>
<Count>0</Count>
</Breakpoints2>
<Interrupts>
<Enabled>1</Enabled>
<Irq0>_ 0 10000 0 10000 1 0 0 100 0 1 "IRQ 1 0x18 CPSR.I"</Irq0>
<Count>1</Count>
</Interrupts>
<MemConfig>
<Base>1</Base>
<Manual>0</Manual>
<Ddf>1</Ddf>
<TypeViol>0</TypeViol>
<Stop>1</Stop>
</MemConfig>
<Aliases>
<Count>0</Count>
<SuppressDialog>0</SuppressDialog>
</Aliases>
<Simulator>
<Freq>10000000</Freq>
<FreqHi>0</FreqHi>
<MultiCoreRunAll>1</MultiCoreRunAll>
</Simulator>
</settings>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,408 @@
;/**************************************************************************/
;/* */
;/* 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"
;
;
SVC_MODE DEFINE 0x13 ; SVC mode
ABT_MODE DEFINE 0x17 ; ABT mode
SYS_MODE DEFINE 0x1F ; SYS mode
THUMB_MASK DEFINE 0x20 ; Thumb bit (5) of CPSR/SPSR
;
EXTERN _tx_thread_system_stack_ptr
EXTERN _tx_initialize_unused_memory
EXTERN _tx_thread_context_save
; EXTERN _tx_thread_vectored_context_save
EXTERN _tx_thread_context_restore
#ifdef TX_ENABLE_IRQ_NESTING
EXTERN _tx_thread_irq_nesting_start
EXTERN _tx_thread_irq_nesting_end
#endif
EXTERN _tx_timer_interrupt
EXTERN ?cstartup
EXTERN _tx_build_options
EXTERN _tx_version_id
;
;
;
;/* Define the FREE_MEM segment that will specify where free memory is
; defined. This must also be located in at the end of other RAM segments
; in the linker control file. The value of this segment is what is passed
; to tx_application_define. */
;
RSEG FREE_MEM:DATA
PUBLIC __tx_free_memory_start
__tx_free_memory_start
DS32 4
;
;
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_initialize_low_level Cortex-R4/MPU/IAR */
;/* 6.1 */
;/* AUTHOR */
;/* */
;/* Scott Larson, 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 */
;/* */
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _tx_initialize_low_level(VOID)
;{
RSEG .text:CODE:NOROOT(2)
ARM
PUBLIC _tx_initialize_low_level
_tx_initialize_low_level
;
; /****** NOTE ****** The IAR 4.11a and above releases call main in SYS mode. */
;
; /* For modules, stay in SYS mode and disable interrupts. */
CPSID i
;
; /* Pickup the start of free memory. */
;
LDR r0, =__tx_free_memory_start ; Get end of non-initialized RAM area
;
; /* Save the system stack pointer. */
; _tx_thread_system_stack_ptr = (VOID_PTR) (sp);
;
; /* Save the first available memory address. */
; _tx_initialize_unused_memory = (VOID_PTR) FREE_MEM;
;
LDR r2, =_tx_initialize_unused_memory ; Pickup unused memory ptr address
STR r0, [r2, #0] ; Save first free memory address
;
; /* Setup Timer for periodic interrupts. */
;
; /* Done, return to caller. */
;
BX lr ; Return to caller
;}
;
;/* Define shells for each of the interrupt vectors. */
;
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_undefined
__tx_undefined
B __tx_undefined ; Undefined handler
;
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_reserved_handler
__tx_reserved_handler
B __tx_reserved_handler ; Reserved exception handler
;
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_irq_handler
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_irq_processing_return
PUBLIC IRQ_Handler
__tx_irq_handler
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
;
; /* 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
;
;
; /* This is an example of a vectored IRQ handler. */
;
; RSEG .text:CODE:NOROOT(2)
; PUBLIC __tx_example_vectored_irq_handler
;__tx_example_vectored_irq_handler
;
; /* Jump to 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 registers
; BL _tx_thread_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 handler is 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
;
;
; /* FIQ Handler */
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_fiq_handler
__tx_fiq_handler
B __tx_fiq_handler ; FIQ interrupt handler
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* __tx_prefetch_handler & __tx_abort_handler Cortex-R4/MPU/IAR */
;/* 6.1 */
;/* AUTHOR */
;/* */
;/* Scott Larson, Microsoft Corporation */
;/* */
;/* DESCRIPTION */
;/* */
;/* This function handles MPU exceptions and fills the */
;/* _txm_module_manager_memory_fault_info struct. */
;/* */
;/* INPUT */
;/* */
;/* None */
;/* */
;/* OUTPUT */
;/* */
;/* None */
;/* */
;/* CALLS */
;/* */
;/* _txm_module_manager_memory_fault_handler */
;/* _tx_execution_thread_exit */
;/* _tx_thread_schedule */
;/* */
;/* CALLED BY */
;/* */
;/* MMU exceptions */
;/* */
;/* RELEASE HISTORY */
;/* */
;/* DATE NAME DESCRIPTION */
;/* */
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
;/* */
;/**************************************************************************/
; *******************************************************************
; MPU Exception Handling
; *******************************************************************
EXTERN _tx_thread_system_state
EXTERN _txm_module_manager_memory_fault_info
EXTERN _tx_thread_current_ptr
EXTERN _txm_module_manager_memory_fault_handler
EXTERN _tx_execution_thread_exit
EXTERN _tx_thread_schedule
RSEG .text:CODE:NOROOT(2)
PUBLIC Prefetch_Handler
PUBLIC Abort_Handler
PUBLIC __tx_prefetch_handler
PUBLIC __tx_abort_handler
__tx_prefetch_handler
__tx_abort_handler
Prefetch_Handler
Abort_Handler
STMDB sp!, {r0-r3} ; Save some working registers
LDR r3, =_tx_thread_system_state ; Pickup address of system state var
LDR r2, [r3, #0] ; Pickup system state
ADD r2, r2, #1 ; Increment the interrupt counter
STR r2, [r3, #0] ; Store it back in the variable
;
; /* Now pickup and store all the fault related information. */
;
; Pickup the memory fault info struct
LDR r3, =_txm_module_manager_memory_fault_info
LDR r0, =_tx_thread_current_ptr ; Build current thread pointer address
LDR r1, [r0] ; Pickup the current thread pointer
STR r1, [r3, #0] ; Save current thread pointer
MRC p15, 0, r0, c6, c0, 0 ; Read DFAR
STR r0, [r3, #8] ; Save DFAR
CMP r0, #0 ; Was it a data or instruction fault?
SUBEQ lr, lr, #4 ; Adjust point of exception for instruction
SUBNE lr, lr, #8 ; Adjust point of exception for data
STR lr, [r3, #4] ; Save point of fault
MRC p15, 0, r0, c5, c0, 0 ; Read DFSR
STR r0, [r3, #12] ; Save DFSR
MRC p15, 0, r0, c6, c0, 2 ; Read IFAR
STR r0, [r3, #16] ; Save IFAR
MRC p15, 0, r0, c5, c0, 1 ; Read IFSR
STR r0, [r3, #20] ; Save IFSR
MOV r0, #0 ; Build zero register
MCR p15, 0, r0, c6, c0, 0 ; Clear DFAR
MCR p15, 0, r0, c5, c0, 0 ; Clear DFSR
MCR p15, 0, r0, c6, c0, 2 ; Clear IFAR
MCR p15, 0, r0, c5, c0, 1 ; Clear IFSR
; Save registers r0-r12
POP {r0-r2}
STR r0, [r3, #28] ; Save r0
STR r1, [r3, #32] ; Save r1
STR r2, [r3, #36] ; Save r2
POP {r0}
STR r0, [r3, #40] ; Save r3
STR r4, [r3, #44] ; Save r4
STR r5, [r3, #48] ; Save r5
STR r6, [r3, #52] ; Save r6
STR r7, [r3, #56] ; Save r7
STR r8, [r3, #60] ; Save r8
STR r9, [r3, #64] ; Save r9
STR r10,[r3, #68] ; Save r10
STR r11,[r3, #72] ; Save r11
STR r12,[r3, #76] ; Save r12
CPS #SYS_MODE ; Enter SYS mode
MOV r0, lr ; Pickup lr
MOV r1, sp ; Pickup sp
CPS #ABT_MODE ; Back to ABT mode
STR r0, [r3, #80] ; Save lr
STR r1, [r3, #24] ; Save sp
MRS r0, SPSR ; Pickup SPSR
STR r0, [r3, #84] ; Save SPSR
ORR r0, r0, #SYS_MODE ; Return into SYS mode
BIC r0, r0, #THUMB_MASK ; Clear THUMB mode
MSR SPSR_c, r0 ; Save SPSR
; Call memory manager fault handler
BL _txm_module_manager_memory_fault_handler
#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
LDR r0, =_tx_thread_system_state ; Pickup address of system state
LDR r1, [r0] ; Pickup system state
SUB r1, r1, #1 ; Decrement
STR r1, [r0] ; Store new system state
MOV r1, #0 ; Build NULL value
LDR r0, =_tx_thread_current_ptr ; Pickup address of current thread pointer
STR r1, [r0] ; Clear current thread pointer
; Return from exception
LDR lr, =_tx_thread_schedule ; Load scheduler address
MOVS pc, lr ; Return to scheduler
; *******************************************************************
; End of MMU exception handling.
; *******************************************************************
;
BUILD_OPTIONS
DC32 _tx_build_options ; Reference to ensure it comes in
VERSION_ID
DC32 _tx_version_id ; Reference to ensure it comes in
END

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,67 @@
SECTION .text:CODE
AAPCS INTERWORK, ROPI, RWPI_COMPATIBLE, VFP_COMPATIBLE
PRESERVE8
/* Define public symbols. */
PUBLIC __txm_module_preamble
/* Define application-specific start/stop entry points for the module. */
EXTERN demo_module_start
/* Define common external refrences. */
EXTERN _txm_module_thread_shell_entry
EXTERN _txm_module_callback_request_thread_entry
EXTERN ROPI$$Length
EXTERN RWPI$$Length
DATA
__txm_module_preamble:
DC32 0x4D4F4455 ; Module ID
DC32 0x6 ; Module Major Version
DC32 0x1 ; Module Minor Version
DC32 32 ; Module Preamble Size in 32-bit words
DC32 0x12345678 ; Module ID (application defined)
DC32 0x00000001 ; Module Properties where:
; Bits 31-24: Compiler ID
; 0 -> IAR
; 1 -> RVDS
; 2 -> GNU
; Bits 23-1: Reserved
; Bit 0: 0 -> Privileged mode execution (no MPU protection)
; 1 -> User mode execution (MPU protection)
DC32 _txm_module_thread_shell_entry - . - 0 ; Module Shell Entry Point
DC32 demo_module_start - . - 0 ; Module Start Thread Entry Point
DC32 0 ; Module Stop Thread Entry Point
DC32 1 ; Module Start/Stop Thread Priority
DC32 1022 ; Module Start/Stop Thread Stack Size
DC32 _txm_module_callback_request_thread_entry - . - 0 ; Module Callback Thread Entry
DC32 1 ; Module Callback Thread Priority
DC32 1022 ; Module Callback Thread Stack Size
DC32 ROPI$$Length ; Module Code Size
DC32 RWPI$$Length ; Module Data Size
DC32 0 ; Reserved 0
DC32 0 ; Reserved 1
DC32 0 ; Reserved 2
DC32 0 ; Reserved 3
DC32 0 ; Reserved 4
DC32 0 ; Reserved 5
DC32 0 ; Reserved 6
DC32 0 ; Reserved 7
DC32 0 ; Reserved 8
DC32 0 ; Reserved 9
DC32 0 ; Reserved 10
DC32 0 ; Reserved 11
DC32 0 ; Reserved 12
DC32 0 ; Reserved 13
DC32 0 ; Reserved 14
DC32 0 ; Reserved 15
END

View File

@@ -0,0 +1,411 @@
/**************************************************************************/
/* */
/* 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-R4/IAR */
/* 6.1.6 */
/* */
/* 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 */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */
/* macro definition, */
/* resulting in version 6.1.6 */
/* */
/**************************************************************************/
#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>
#include <intrinsics.h>
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <yvals.h>
#endif
/* 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. */
#define TX_INT_DISABLE 0x80 /* Disable IRQ interrupts */
#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_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
#endif
#else
ULONG _tx_misra_time_stamp_get(VOID);
#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get()
#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_IRQ_NESTING
#define TX_IRQ_NESTING_ENABLED 1
#else
#define TX_IRQ_NESTING_ENABLED 0
#endif
#define TX_PORT_SPECIFIC_BUILD_OPTIONS (TX_IRQ_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. */
#ifdef TX_MISRA_ENABLE
#define TX_DISABLE_INLINE
#else
#define TX_INLINE_INITIALIZATION
#endif
/* 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. */
#ifndef TX_MISRA_ENABLE
#ifdef TX_ENABLE_STACK_CHECKING
#undef TX_DISABLE_STACK_FILLING
#endif
#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
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#define TX_THREAD_EXTENSION_2 ULONG tx_thread_vfp_enable; \
VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
ULONG tx_thread_module_user_mode; \
VOID *tx_thread_module_kernel_stack_start; \
VOID *tx_thread_module_kernel_stack_end; \
ULONG tx_thread_module_kernel_stack_size; \
VOID *tx_thread_module_stack_ptr; \
VOID *tx_thread_module_stack_start; \
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved; \
VOID *tx_thread_iar_tls_pointer;
#else
#define TX_THREAD_EXTENSION_2 ULONG tx_thread_vfp_enable; \
VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
ULONG tx_thread_module_user_mode; \
VOID *tx_thread_module_kernel_stack_start; \
VOID *tx_thread_module_kernel_stack_end; \
ULONG tx_thread_module_kernel_stack_size; \
VOID *tx_thread_module_stack_ptr; \
VOID *tx_thread_module_stack_start; \
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved;
#endif
#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 VOID *tx_event_flags_group_module_instance; \
VOID (*tx_event_flags_group_set_module_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *group_ptr);
#define TX_MUTEX_EXTENSION
#define TX_QUEUE_EXTENSION VOID *tx_queue_module_instance; \
VOID (*tx_queue_send_module_notify)(struct TX_QUEUE_STRUCT *queue_ptr);
#define TX_SEMAPHORE_EXTENSION VOID *tx_semaphore_module_instance; \
VOID (*tx_semaphore_put_module_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr);
#define TX_TIMER_EXTENSION VOID *tx_timer_module_instance; \
VOID (*tx_timer_module_expiration_function)(ULONG id);
/* 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. */
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#if (__VER__ < 8000000)
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate();
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \
thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL;
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0);
#else
void *_tx_iar_create_per_thread_tls_area(void);
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr);
void __iar_Initlocks(void);
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area();
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \
thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0);
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0);
#endif
#else
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
#endif
#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. */
#ifndef TX_DISABLE_INLINE
#if __CORE__ > __ARM4TM__
#if __CPU_MODE__ == 2
#define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \
b = (UINT) __CLZ(m); \
b = 31 - b;
#endif
#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. */
/* First, check and see what mode the file is being compiled in. The IAR compiler
defines __CPU_MODE__ to 1, if the Thumb mode is present, and 2 if ARM 32-bit mode
is present. If ARM 32-bit mode is present, the fast CPSR manipulation macros
are available. Otherwise, if Thumb mode is present, we must use function calls. */
#ifdef TX_DISABLE_INLINE
UINT _tx_thread_interrupt_disable(void);
void _tx_thread_interrupt_restore(UINT old_posture);
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
#else
#if __CPU_MODE__ == 2
#if (__VER__ < 8002000)
__intrinsic unsigned long __get_CPSR();
__intrinsic void __set_CPSR( unsigned long );
#endif
#if (__VER__ < 8002000)
#define TX_INTERRUPT_SAVE_AREA ULONG interrupt_save;
#else
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
#endif
#define TX_DISABLE interrupt_save = __get_CPSR(); \
__set_CPSR(interrupt_save | TX_INT_DISABLE);
#define TX_RESTORE __set_CPSR(interrupt_save);
#else
UINT _tx_thread_interrupt_disable(void);
void _tx_thread_interrupt_restore(UINT old_posture);
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
#endif
#endif
/* 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 VFP extension for the Cortex-R4. 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 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-R4/IAR Version 6.1.6 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
#else
extern CHAR _tx_version_id[];
#endif
#endif
#endif

View File

@@ -0,0 +1,347 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-R4/MPU/IAR */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the basic module constants, interface structures, */
/* and function prototypes. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
#ifndef TXM_MODULE_PORT_H
#define TXM_MODULE_PORT_H
/* Determine if the optional Modules user define file should be used. */
#ifdef TXM_MODULE_INCLUDE_USER_DEFINE_FILE
/* Yes, include the user defines in txm_module_user.h. The defines in this file may
alternately be defined on the command line. */
#include "txm_module_user.h"
#endif
/* It is assumed that the base ThreadX tx_port.h file has been modified to add the
following extensions to the ThreadX thread control block (this code should replace
the corresponding macro define in tx_port.h):
#define TX_THREAD_EXTENSION_2 ULONG tx_thread_vfp_enable; \
VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
ULONG tx_thread_module_user_mode; \
VOID *tx_thread_module_kernel_stack_start; \
VOID *tx_thread_module_kernel_stack_end; \
ULONG tx_thread_module_kernel_stack_size; \
VOID *tx_thread_module_stack_ptr; \
VOID *tx_thread_module_stack_start; \
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved; \
VOID *tx_thread_iar_tls_pointer;
The following extensions must also be defined in tx_port.h:
#define TX_EVENT_FLAGS_GROUP_EXTENSION VOID *tx_event_flags_group_module_instance; \
VOID (*tx_event_flags_group_set_module_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *group_ptr);
#define TX_QUEUE_EXTENSION VOID *tx_queue_module_instance; \
VOID (*tx_queue_send_module_notify)(struct TX_QUEUE_STRUCT *queue_ptr);
#define TX_SEMAPHORE_EXTENSION VOID *tx_semaphore_module_instance; \
VOID (*tx_semaphore_put_module_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr);
#define TX_TIMER_EXTENSION VOID *tx_timer_module_instance; \
VOID (*tx_timer_module_expiration_function)(ULONG id);
*/
/* Define the kernel stack size for a module thread. */
#ifndef TXM_MODULE_KERNEL_STACK_SIZE
#define TXM_MODULE_KERNEL_STACK_SIZE 512
#endif
/* For the following 3 access control settings, change TEX and C, B, S (bits 5 through 0)
* to reflect your system memory attributes (cache, shareable, memory type). */
/* Code region access control: read-only, outer & inner write-back, normal memory, shareable. */
#define TXM_MODULE_MPU_CODE_ACCESS_CONTROL 0x00000607
/* Data region access control: execute never, read/write, outer & inner write-back, normal memory, shareable. */
#define TXM_MODULE_MPU_DATA_ACCESS_CONTROL 0x00001307
/* Shared region access control: execute never, read-only, outer & inner write-back, normal memory, shareable. */
#define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x00001207
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
#define TXM_MODULE_RVDS_COMPILER 0x01000000
#define TXM_MODULE_GNU_COMPILER 0x02000000
#define TXM_MODULE_COMPILER_MASK 0xFF000000
#define TXM_MODULE_OPTIONS_MASK 0x000000FF
/* Define the properties for this particular module port. */
#define TXM_MODULE_MEMORY_PROTECTION_ENABLED
#ifdef TXM_MODULE_MEMORY_PROTECTION_ENABLED
#define TXM_MODULE_REQUIRE_ALLOCATED_OBJECT_MEMORY
#else
#define TXM_MODULE_REQUIRE_LOCAL_OBJECT_MEMORY
#endif
#define TXM_MODULE_USER_MODE 0x00000001
#define TXM_MODULE_MEMORY_PROTECTION 0x00000001
/* Define the supported options for this module. */
#define TXM_MODULE_MANAGER_SUPPORTED_OPTIONS (TXM_MODULE_MEMORY_PROTECTION)
#define TXM_MODULE_MANAGER_REQUIRED_OPTIONS 0
/* Define offset adjustments according to the compiler used to build the module. */
#define TXM_MODULE_IAR_SHELL_ADJUST 24
#define TXM_MODULE_IAR_START_ADJUST 28
#define TXM_MODULE_IAR_STOP_ADJUST 32
#define TXM_MODULE_IAR_CALLBACK_ADJUST 44
#define TXM_MODULE_RVDS_SHELL_ADJUST 0
#define TXM_MODULE_RVDS_START_ADJUST 0
#define TXM_MODULE_RVDS_STOP_ADJUST 0
#define TXM_MODULE_RVDS_CALLBACK_ADJUST 0
#define TXM_MODULE_GNU_SHELL_ADJUST 24
#define TXM_MODULE_GNU_START_ADJUST 28
#define TXM_MODULE_GNU_STOP_ADJUST 32
#define TXM_MODULE_GNU_CALLBACK_ADJUST 44
/* Define other module port-specific constants. */
/* Define INLINE_DECLARE to inline for IAR compiler. */
#define INLINE_DECLARE inline
/* Define the number of MPU entries assigned to the code and data sections.
On Cortex-R parts, there are 12 total entries. ThreadX uses one for access
to the kernel entry function, thus 11 remain for code and data protection. */
#define TXM_MODULE_MPU_TOTAL_ENTRIES 12
#define TXM_MODULE_MPU_CODE_ENTRIES 4
#define TXM_MODULE_MPU_DATA_ENTRIES 4
#define TXM_MODULE_MPU_SHARED_ENTRIES 3
#define TXM_MODULE_MPU_KERNEL_ENTRY_INDEX 0
#define TXM_MODULE_MPU_SHARED_INDEX 9
/* There are 3 registers to set up each MPU region: DRACR, DRBAR, DRSR. */
#define TXM_MODULE_MPU_REGISTER_COUNT 3
#define TXM_ENABLE_REGION 0x01
/* Shared memory region attributes. */
#define TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE 1
#define TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT 0x00000100
typedef struct TXM_MODULE_MPU_INFO_STRUCT
{
ULONG txm_module_mpu_region_address;
ULONG txm_module_mpu_region_size;
ULONG txm_module_mpu_region_attributes;
} TXM_MODULE_MPU_INFO;
/* Define the port-extensions to the module manager instance structure. */
#define TXM_MODULE_MANAGER_PORT_EXTENSION \
TXM_MODULE_MPU_INFO txm_module_instance_mpu_registers[TXM_MODULE_MPU_TOTAL_ENTRIES]; \
ULONG txm_module_instance_shared_memory_count; \
ULONG txm_module_instance_shared_memory_address[TXM_MODULE_MPU_SHARED_ENTRIES]; \
ULONG txm_module_instance_shared_memory_length[TXM_MODULE_MPU_SHARED_ENTRIES];
/* Define the memory fault information structure that is populated when a memory fault occurs. */
typedef struct TXM_MODULE_MANAGER_MEMORY_FAULT_INFO_STRUCT
{
TX_THREAD *txm_module_manager_memory_fault_info_thread_ptr;
VOID *txm_module_manager_memory_fault_info_code_location;
ULONG txm_module_manager_memory_fault_info_dfar;
ULONG txm_module_manager_memory_fault_info_dfsr;
ULONG txm_module_manager_memory_fault_info_ifar;
ULONG txm_module_manager_memory_fault_info_ifsr;
ULONG txm_module_manager_memory_fault_info_sp;
ULONG txm_module_manager_memory_fault_info_r0;
ULONG txm_module_manager_memory_fault_info_r1;
ULONG txm_module_manager_memory_fault_info_r2;
ULONG txm_module_manager_memory_fault_info_r3;
ULONG txm_module_manager_memory_fault_info_r4;
ULONG txm_module_manager_memory_fault_info_r5;
ULONG txm_module_manager_memory_fault_info_r6;
ULONG txm_module_manager_memory_fault_info_r7;
ULONG txm_module_manager_memory_fault_info_r8;
ULONG txm_module_manager_memory_fault_info_r9;
ULONG txm_module_manager_memory_fault_info_r10;
ULONG txm_module_manager_memory_fault_info_r11;
ULONG txm_module_manager_memory_fault_info_r12;
ULONG txm_module_manager_memory_fault_info_lr;
ULONG txm_module_manager_memory_fault_info_cpsr;
} TXM_MODULE_MANAGER_MEMORY_FAULT_INFO;
#define TXM_MODULE_MANAGER_FAULT_INFO \
TXM_MODULE_MANAGER_MEMORY_FAULT_INFO _txm_module_manager_memory_fault_info;
/* Define the macro to check the stack available in dispatch. */
#define TXM_MODULE_MANAGER_CHECK_STACK_AVAILABLE
/* Define the macro to check the code alignment. */
#define TXM_MODULE_MANAGER_CHECK_CODE_ALIGNMENT(module_location, code_alignment) \
{ \
ULONG temp; \
temp = (ULONG) module_location; \
temp = temp & (code_alignment - 1); \
if (temp) \
{ \
_tx_mutex_put(&_txm_module_manager_mutex); \
return(TXM_MODULE_ALIGNMENT_ERROR); \
} \
}
/* Define the macro to adjust the alignment and size for code/data areas. */
#define TXM_MODULE_MANAGER_ALIGNMENT_ADJUST(module_preamble, code_size, code_alignment, data_size, data_alignment) _txm_module_manager_alignment_adjust(module_preamble, &code_size, &code_alignment, &data_size, &data_alignment);
/* Define the macro to adjust the symbols in the module preamble. */
#define TXM_MODULE_MANAGER_CALCULATE_ADJUSTMENTS(properties, shell_function_adjust, start_function_adjust, stop_function_adjust, callback_function_adjust) \
if ((properties & TXM_MODULE_COMPILER_MASK) == TXM_MODULE_IAR_COMPILER) \
{ \
shell_function_adjust = TXM_MODULE_IAR_SHELL_ADJUST; \
start_function_adjust = TXM_MODULE_IAR_START_ADJUST; \
stop_function_adjust = TXM_MODULE_IAR_STOP_ADJUST; \
callback_function_adjust = TXM_MODULE_IAR_CALLBACK_ADJUST; \
} \
else if ((properties & TXM_MODULE_COMPILER_MASK) == TXM_MODULE_RVDS_COMPILER) \
{ \
shell_function_adjust = TXM_MODULE_RVDS_SHELL_ADJUST; \
start_function_adjust = TXM_MODULE_RVDS_START_ADJUST; \
stop_function_adjust = TXM_MODULE_RVDS_STOP_ADJUST; \
callback_function_adjust = TXM_MODULE_RVDS_CALLBACK_ADJUST; \
} \
else \
{ \
shell_function_adjust = TXM_MODULE_GNU_SHELL_ADJUST; \
start_function_adjust = TXM_MODULE_GNU_START_ADJUST; \
stop_function_adjust = TXM_MODULE_GNU_STOP_ADJUST; \
callback_function_adjust = TXM_MODULE_GNU_CALLBACK_ADJUST; \
}
/* Define the macro to populate the thread control block with module port-specific information.
Check if the module is in user mode and set up txm_module_thread_entry_info_kernel_call_dispatcher accordingly.
*/
#define TXM_MODULE_MANAGER_THREAD_SETUP(thread_ptr, module_instance) \
thread_ptr -> tx_thread_module_current_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION; \
thread_ptr -> tx_thread_module_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION; \
if (thread_ptr -> tx_thread_module_user_mode) \
{ \
thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher = _txm_module_manager_user_mode_entry; \
} \
else \
{ \
thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher = _txm_module_manager_kernel_dispatch; \
}
/* Define the macro to populate the module control block with module port-specific information.
If memory protection is enabled, set up the MPU registers.
*/
#define TXM_MODULE_MANAGER_MODULE_SETUP(module_instance) \
if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION) \
{ \
_txm_module_manager_mm_register_setup(module_instance); \
} \
else \
{ \
/* Do nothing. */ \
}
/* Define the macro to perform port-specific functions when unloading the module. */
/* Nothing needs to be done for this port. */
#define TXM_MODULE_MANAGER_MODULE_UNLOAD(module_instance)
/* Define the macros to perform port-specific checks when passing pointers to the kernel. */
/* Define macro to make sure object is inside the module's data. */
#define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \
_txm_module_manager_inside_data_check(module_instance, obj_ptr, obj_size)
/* Define some internal prototypes to this module port. */
#ifndef TX_SOURCE_CODE
#define txm_module_manager_memory_fault_notify _txm_module_manager_memory_fault_notify
#endif
#define TXM_MODULE_MANAGER_ADDITIONAL_PROTOTYPES \
VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, ULONG *code_size, ULONG *code_alignment, ULONG *data_size, ULONG *data_alignment); \
ULONG _txm_module_manager_data_pointer_check(TXM_MODULE_INSTANCE *module_instance, ULONG pointer); \
VOID _txm_module_manager_memory_fault_handler(VOID); \
UINT _txm_module_manager_memory_fault_notify(VOID (*notify_function)(TX_THREAD *, TXM_MODULE_INSTANCE *)); \
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance); \
ULONG _txm_power_of_two_block_size(ULONG size); \
ULONG _txm_module_manager_calculate_srd_bits(ULONG block_size, ULONG length); \
ULONG _txm_module_manager_region_size_get(ULONG block_size); \
UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance, ULONG obj_ptr, UINT obj_size);
#define TXM_MODULE_MANAGER_VERSION_ID \
CHAR _txm_module_manager_version_id[] = \
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-R4/MPU/IAR Version 6.1 *";
#endif

View File

@@ -0,0 +1,174 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module */
/** */
/**************************************************************************/
/**************************************************************************/
#ifndef TXM_MODULE
#define TXM_MODULE
#endif
#ifndef TX_SOURCE_CODE
#define TX_SOURCE_CODE
#endif
/* Include necessary system files. */
#include "txm_module.h"
#include "tx_thread.h"
/* Define the global module entry pointer from the start thread of the module. */
TXM_MODULE_THREAD_ENTRY_INFO *_txm_module_entry_info;
/* Define the dispatch function pointer used in the module implementation. */
ULONG (*_txm_module_kernel_call_dispatcher)(ULONG kernel_request, ULONG param_1, ULONG param_2, ULONG param3);
/* Define the IAR startup code that clears the uninitialized global data and sets up the
preset global variables. */
extern VOID __iar_data_init3(VOID);
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_thread_shell_entry Cortex-R4/MPU/IAR */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function calls the specified entry function of the thread. It */
/* also provides a place for the thread's entry function to return. */
/* If the thread returns, this function places the thread in a */
/* "COMPLETED" state. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to current thread */
/* thread_info Pointer to thread entry info */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* __iar_data_init3 IAR global initialization function*/
/* thread_entry Thread's entry function */
/* tx_thread_resume Resume the module callback thread */
/* _txm_module_thread_system_suspend Module thread suspension routine */
/* */
/* CALLED BY */
/* */
/* Initial thread stack frame */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _txm_module_thread_shell_entry(TX_THREAD *thread_ptr, TXM_MODULE_THREAD_ENTRY_INFO *thread_info)
{
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
VOID (*entry_exit_notify)(TX_THREAD *, UINT);
#endif
/* Determine if this is the start thread. If so, we must prepare the module for
execution. If not, simply skip the C startup code. */
if (thread_info -> txm_module_thread_entry_info_start_thread)
{
/* Initialize the IAR C environment. */
__iar_data_init3();
/* Save the entry info pointer, for later use. */
_txm_module_entry_info = thread_info;
/* Save the kernel function dispatch address. This is used to make all resident calls from
the module. */
_txm_module_kernel_call_dispatcher = thread_info -> txm_module_thread_entry_info_kernel_call_dispatcher;
/* Ensure that we have a valid pointer. */
while (!_txm_module_kernel_call_dispatcher)
{
/* Loop here, if an error is present getting the dispatch function pointer!
An error here typically indicates the resident portion of _tx_thread_schedule
is not supporting the trap to obtain the function pointer. */
}
/* Resume the module's callback thread, already created in the manager. */
_txe_thread_resume(thread_info -> txm_module_thread_entry_info_callback_request_thread);
}
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
/* Pickup the entry/exit application callback routine. */
entry_exit_notify = thread_info -> txm_module_thread_entry_info_exit_notify;
/* Determine if an application callback routine is specified. */
if (entry_exit_notify != TX_NULL)
{
/* Yes, notify application that this thread has been entered! */
(entry_exit_notify)(thread_ptr, TX_THREAD_ENTRY);
}
#endif
/* Call current thread's entry function. */
(thread_info -> txm_module_thread_entry_info_entry) (thread_info -> txm_module_thread_entry_info_parameter);
/* Suspend thread with a "completed" state. */
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
/* Pickup the entry/exit application callback routine again. */
entry_exit_notify = thread_info -> txm_module_thread_entry_info_exit_notify;
/* Determine if an application callback routine is specified. */
if (entry_exit_notify != TX_NULL)
{
/* Yes, notify application that this thread has exited! */
(entry_exit_notify)(thread_ptr, TX_THREAD_EXIT);
}
#endif
/* Call actual thread suspension routine. */
_txm_module_thread_system_suspend(thread_ptr);
#ifdef TX_SAFETY_CRITICAL
/* If we ever get here, raise safety critical exception. */
TX_SAFETY_CRITICAL_EXCEPTION(__FILE__, __LINE__, 0);
#endif
}

View File

@@ -0,0 +1,804 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** IAR Multithreaded Library Support */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Define IAR library for tools prior to version 8. */
#if (__VER__ < 8000000)
/* IAR version 7 and below. */
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_initialize.h"
#include "tx_thread.h"
#include "tx_mutex.h"
/* This implementation requires that the following macros are defined in the
tx_port.h file and <yvals.h> is included with the following code segments:
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <yvals.h>
#endif
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer;
#else
#define TX_THREAD_EXTENSION_2
#endif
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate();
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \
thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL;
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0);
#else
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
#endif
This should be done automatically if TX_ENABLE_IAR_LIBRARY_SUPPORT is defined while building the ThreadX library and the
application.
Finally, the project options General Options -> Library Configuration should have the "Enable thread support in library" box selected.
*/
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <yvals.h>
#if _MULTI_THREAD
TX_MUTEX __tx_iar_system_lock_mutexes[_MAX_LOCK];
UINT __tx_iar_system_lock_next_free_mutex = 0;
/* Define error counters, just for debug purposes. */
UINT __tx_iar_system_lock_no_mutexes;
UINT __tx_iar_system_lock_internal_errors;
UINT __tx_iar_system_lock_isr_caller;
/* Define the TLS access function for the IAR library. */
void _DLIB_TLS_MEMORY *__iar_dlib_perthread_access(void _DLIB_TLS_MEMORY *symbp)
{
char _DLIB_TLS_MEMORY *p = 0;
/* Is there a current thread? */
if (_tx_thread_current_ptr)
p = (char _DLIB_TLS_MEMORY *) _tx_thread_current_ptr -> tx_thread_iar_tls_pointer;
else
p = (void _DLIB_TLS_MEMORY *) __segment_begin("__DLIB_PERTHREAD");
p += __IAR_DLIB_PERTHREAD_SYMBOL_OFFSET(symbp);
return (void _DLIB_TLS_MEMORY *) p;
}
/* Define mutexes for IAR library. */
void __iar_system_Mtxinit(__iar_Rmtx *m)
{
UINT i;
UINT status;
TX_MUTEX *mutex_ptr;
/* First, find a free mutex in the list. */
for (i = 0; i < _MAX_LOCK; i++)
{
/* Setup a pointer to the start of the next free mutex. */
mutex_ptr = &__tx_iar_system_lock_mutexes[__tx_iar_system_lock_next_free_mutex++];
/* Check for wrap-around on the next free mutex. */
if (__tx_iar_system_lock_next_free_mutex >= _MAX_LOCK)
{
/* Yes, set the free index back to 0. */
__tx_iar_system_lock_next_free_mutex = 0;
}
/* Is this mutex free? */
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
{
/* Yes, this mutex is free, get out of the loop! */
break;
}
}
/* Determine if a free mutex was found. */
if (i >= _MAX_LOCK)
{
/* Error! No more free mutexes! */
/* Increment the no mutexes error counter. */
__tx_iar_system_lock_no_mutexes++;
/* Set return pointer to NULL. */
*m = TX_NULL;
/* Return. */
return;
}
/* Now create the ThreadX mutex for the IAR library. */
status = _tx_mutex_create(mutex_ptr, "IAR System Library Lock", TX_NO_INHERIT);
/* Determine if the creation was successful. */
if (status == TX_SUCCESS)
{
/* Yes, successful creation, return mutex pointer. */
*m = (VOID *) mutex_ptr;
}
else
{
/* Increment the internal error counter. */
__tx_iar_system_lock_internal_errors++;
/* Return a NULL pointer to indicate an error. */
*m = TX_NULL;
}
}
void __iar_system_Mtxdst(__iar_Rmtx *m)
{
/* Simply delete the mutex. */
_tx_mutex_delete((TX_MUTEX *) *m);
}
void __iar_system_Mtxlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex locks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Get the mutex. */
status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_system_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_system_lock_isr_caller++;
}
}
void __iar_system_Mtxunlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex unlocks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Release the mutex. */
status = _tx_mutex_put((TX_MUTEX *) *m);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_system_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_system_lock_isr_caller++;
}
}
#if _DLIB_FILE_DESCRIPTOR
TX_MUTEX __tx_iar_file_lock_mutexes[_MAX_FLOCK];
UINT __tx_iar_file_lock_next_free_mutex = 0;
/* Define error counters, just for debug purposes. */
UINT __tx_iar_file_lock_no_mutexes;
UINT __tx_iar_file_lock_internal_errors;
UINT __tx_iar_file_lock_isr_caller;
void __iar_file_Mtxinit(__iar_Rmtx *m)
{
UINT i;
UINT status;
TX_MUTEX *mutex_ptr;
/* First, find a free mutex in the list. */
for (i = 0; i < _MAX_FLOCK; i++)
{
/* Setup a pointer to the start of the next free mutex. */
mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++];
/* Check for wrap-around on the next free mutex. */
if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK)
{
/* Yes, set the free index back to 0. */
__tx_iar_file_lock_next_free_mutex = 0;
}
/* Is this mutex free? */
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
{
/* Yes, this mutex is free, get out of the loop! */
break;
}
}
/* Determine if a free mutex was found. */
if (i >= _MAX_LOCK)
{
/* Error! No more free mutexes! */
/* Increment the no mutexes error counter. */
__tx_iar_file_lock_no_mutexes++;
/* Set return pointer to NULL. */
*m = TX_NULL;
/* Return. */
return;
}
/* Now create the ThreadX mutex for the IAR library. */
status = _tx_mutex_create(mutex_ptr, "IAR File Library Lock", TX_NO_INHERIT);
/* Determine if the creation was successful. */
if (status == TX_SUCCESS)
{
/* Yes, successful creation, return mutex pointer. */
*m = (VOID *) mutex_ptr;
}
else
{
/* Increment the internal error counter. */
__tx_iar_file_lock_internal_errors++;
/* Return a NULL pointer to indicate an error. */
*m = TX_NULL;
}
}
void __iar_file_Mtxdst(__iar_Rmtx *m)
{
/* Simply delete the mutex. */
_tx_mutex_delete((TX_MUTEX *) *m);
}
void __iar_file_Mtxlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex locks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Get the mutex. */
status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_file_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_file_lock_isr_caller++;
}
}
void __iar_file_Mtxunlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex unlocks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Release the mutex. */
status = _tx_mutex_put((TX_MUTEX *) *m);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_file_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_file_lock_isr_caller++;
}
}
#endif /* _DLIB_FILE_DESCRIPTOR */
#endif /* _MULTI_THREAD */
#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
#else /* IAR version 8 and above. */
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_initialize.h"
#include "tx_thread.h"
#include "tx_mutex.h"
/* This implementation requires that the following macros are defined in the
tx_port.h file and <yvals.h> is included with the following code segments:
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <yvals.h>
#endif
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer;
#else
#define TX_THREAD_EXTENSION_2
#endif
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
void *_tx_iar_create_per_thread_tls_area(void);
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr);
void __iar_Initlocks(void);
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate();
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {__iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \
thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0);
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0);
#else
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
#endif
This should be done automatically if TX_ENABLE_IAR_LIBRARY_SUPPORT is defined while building the ThreadX library and the
application.
Finally, the project options General Options -> Library Configuration should have the "Enable thread support in library" box selected.
*/
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <DLib_threads.h>
void * __aeabi_read_tp();
void* _tx_iar_create_per_thread_tls_area();
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr);
#pragma section="__iar_tls$$DATA"
/* Define the TLS access function for the IAR library. */
void * __aeabi_read_tp(void)
{
void *p = 0;
TX_THREAD *thread_ptr = _tx_thread_current_ptr;
if (thread_ptr)
{
p = thread_ptr->tx_thread_iar_tls_pointer;
}
else
{
p = __section_begin("__iar_tls$$DATA");
}
return p;
}
/* Define the TLS creation and destruction to use malloc/free. */
void* _tx_iar_create_per_thread_tls_area()
{
UINT tls_size = __iar_tls_size();
/* Get memory for TLS. */
void *p = malloc(tls_size);
/* Initialize TLS-area and run constructors for objects in TLS */
__iar_tls_init(p);
return p;
}
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr)
{
/* Destroy objects living in TLS */
__call_thread_dtors();
free(tls_ptr);
}
#ifndef _MAX_LOCK
#define _MAX_LOCK 4
#endif
static TX_MUTEX __tx_iar_system_lock_mutexes[_MAX_LOCK];
static UINT __tx_iar_system_lock_next_free_mutex = 0;
/* Define error counters, just for debug purposes. */
UINT __tx_iar_system_lock_no_mutexes;
UINT __tx_iar_system_lock_internal_errors;
UINT __tx_iar_system_lock_isr_caller;
/* Define mutexes for IAR library. */
void __iar_system_Mtxinit(__iar_Rmtx *m)
{
UINT i;
UINT status;
TX_MUTEX *mutex_ptr;
/* First, find a free mutex in the list. */
for (i = 0; i < _MAX_LOCK; i++)
{
/* Setup a pointer to the start of the next free mutex. */
mutex_ptr = &__tx_iar_system_lock_mutexes[__tx_iar_system_lock_next_free_mutex++];
/* Check for wrap-around on the next free mutex. */
if (__tx_iar_system_lock_next_free_mutex >= _MAX_LOCK)
{
/* Yes, set the free index back to 0. */
__tx_iar_system_lock_next_free_mutex = 0;
}
/* Is this mutex free? */
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
{
/* Yes, this mutex is free, get out of the loop! */
break;
}
}
/* Determine if a free mutex was found. */
if (i >= _MAX_LOCK)
{
/* Error! No more free mutexes! */
/* Increment the no mutexes error counter. */
__tx_iar_system_lock_no_mutexes++;
/* Set return pointer to NULL. */
*m = TX_NULL;
/* Return. */
return;
}
/* Now create the ThreadX mutex for the IAR library. */
status = _tx_mutex_create(mutex_ptr, "IAR System Library Lock", TX_NO_INHERIT);
/* Determine if the creation was successful. */
if (status == TX_SUCCESS)
{
/* Yes, successful creation, return mutex pointer. */
*m = (VOID *) mutex_ptr;
}
else
{
/* Increment the internal error counter. */
__tx_iar_system_lock_internal_errors++;
/* Return a NULL pointer to indicate an error. */
*m = TX_NULL;
}
}
void __iar_system_Mtxdst(__iar_Rmtx *m)
{
/* Simply delete the mutex. */
_tx_mutex_delete((TX_MUTEX *) *m);
}
void __iar_system_Mtxlock(__iar_Rmtx *m)
{
if (*m)
{
UINT status;
/* Determine the caller's context. Mutex locks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Get the mutex. */
status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_system_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_system_lock_isr_caller++;
}
}
}
void __iar_system_Mtxunlock(__iar_Rmtx *m)
{
if (*m)
{
UINT status;
/* Determine the caller's context. Mutex unlocks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Release the mutex. */
status = _tx_mutex_put((TX_MUTEX *) *m);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_system_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_system_lock_isr_caller++;
}
}
}
#if _DLIB_FILE_DESCRIPTOR
#include <stdio.h> /* Added to get access to FOPEN_MAX */
#ifndef _MAX_FLOCK
#define _MAX_FLOCK FOPEN_MAX /* Define _MAX_FLOCK as the maximum number of open files */
#endif
TX_MUTEX __tx_iar_file_lock_mutexes[_MAX_FLOCK];
UINT __tx_iar_file_lock_next_free_mutex = 0;
/* Define error counters, just for debug purposes. */
UINT __tx_iar_file_lock_no_mutexes;
UINT __tx_iar_file_lock_internal_errors;
UINT __tx_iar_file_lock_isr_caller;
void __iar_file_Mtxinit(__iar_Rmtx *m)
{
UINT i;
UINT status;
TX_MUTEX *mutex_ptr;
/* First, find a free mutex in the list. */
for (i = 0; i < _MAX_FLOCK; i++)
{
/* Setup a pointer to the start of the next free mutex. */
mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++];
/* Check for wrap-around on the next free mutex. */
if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK)
{
/* Yes, set the free index back to 0. */
__tx_iar_file_lock_next_free_mutex = 0;
}
/* Is this mutex free? */
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
{
/* Yes, this mutex is free, get out of the loop! */
break;
}
}
/* Determine if a free mutex was found. */
if (i >= _MAX_LOCK)
{
/* Error! No more free mutexes! */
/* Increment the no mutexes error counter. */
__tx_iar_file_lock_no_mutexes++;
/* Set return pointer to NULL. */
*m = TX_NULL;
/* Return. */
return;
}
/* Now create the ThreadX mutex for the IAR library. */
status = _tx_mutex_create(mutex_ptr, "IAR File Library Lock", TX_NO_INHERIT);
/* Determine if the creation was successful. */
if (status == TX_SUCCESS)
{
/* Yes, successful creation, return mutex pointer. */
*m = (VOID *) mutex_ptr;
}
else
{
/* Increment the internal error counter. */
__tx_iar_file_lock_internal_errors++;
/* Return a NULL pointer to indicate an error. */
*m = TX_NULL;
}
}
void __iar_file_Mtxdst(__iar_Rmtx *m)
{
/* Simply delete the mutex. */
_tx_mutex_delete((TX_MUTEX *) *m);
}
void __iar_file_Mtxlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex locks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Get the mutex. */
status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_file_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_file_lock_isr_caller++;
}
}
void __iar_file_Mtxunlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex unlocks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Release the mutex. */
status = _tx_mutex_put((TX_MUTEX *) *m);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_file_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_file_lock_isr_caller++;
}
}
#endif /* _DLIB_FILE_DESCRIPTOR */
#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
#endif /* IAR version 8 and above. */

View File

@@ -0,0 +1,239 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
IRQ_MODE EQU 0x12 ; IRQ mode
SVC_MODE EQU 0x13 ; SVC mode
SYS_MODE EQU 0x1F ; SYS mode
DISABLE_INTS DEFINE 0x80 ; Disable IRQ interrupts
THUMB_MASK DEFINE 0x20 ; Thumb bit mask
;
EXTERN _tx_thread_system_state
EXTERN _tx_thread_current_ptr
EXTERN _tx_thread_execute_ptr
EXTERN _tx_timer_time_slice
EXTERN _tx_thread_schedule
EXTERN _tx_thread_preempt_disable
EXTERN _tx_execution_isr_exit
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_context_restore Cortex-R4/MPU/IAR */
;/* 6.1 */
;/* AUTHOR */
;/* */
;/* Scott Larson, 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 */
;/* */
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _tx_thread_context_restore(VOID)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_context_restore
ARM
_tx_thread_context_restore
;
; /* Lockout interrupts. */
;
CPSID i ; Disable IRQ 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 var
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)
CPS #SYS_MODE ; Enter SYS mode
STR r1, [sp, #-4]! ; Save point of interrupt on thread's stack
STMDB sp!, {r4-r12, lr} ; Save upper half of registers on thread's stack
MOV r4, r3 ; Save SPSR in r4
CPS #IRQ_MODE ; Enter IRQ mode
LDMIA sp!, {r0-r3} ; Recover r0-r3
CPS #SYS_MODE ; Enter SYS 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, #0] ; Pickup current thread pointer
#ifdef __ARMVFP__
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!, {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();
;
CPS #IRQ_MODE ; Enter IRQ mode
MRS r1, SPSR ; Get SPSR
ORR r1, r1, #SYS_MODE ; Change to SYS Mode
BIC r1, r1, #THUMB_MASK ; Clear thumb bit - slarson
MSR SPSR_cxsf, r1 ; Put SYS Mode in SPSR
LDR lr, =_tx_thread_schedule ; Load scheduler address
MOVS pc, lr ; Return to scheduler
; }
;
__tx_thread_idle_system_restore
;
; /* Just return back to the scheduler! */
;
LDR lr, =_tx_thread_schedule ; Load scheduler address
MOVS pc, lr ; Return to scheduler
;}
;
END

View File

@@ -0,0 +1,188 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
EXTERN _tx_thread_system_state
EXTERN _tx_thread_current_ptr
EXTERN __tx_irq_processing_return
EXTERN _tx_execution_isr_enter
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_context_save Cortex-R4/IAR */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _tx_thread_context_save(VOID)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_context_save
ARM
_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
LDR r3, =_tx_thread_system_state ; Pickup address of system state var
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
;
; /* 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, #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 occured 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
;
; }
;}
;
;
;
END

View File

@@ -0,0 +1,89 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
INT_MASK DEFINE 0x80 ; Interrupt bit mask
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_interrupt_control Cortex-R4/IAR */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
;/* */
;/**************************************************************************/
;UINT _tx_thread_interrupt_control(UINT new_posture)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_interrupt_control
ARM
_tx_thread_interrupt_control
;
; /* Pickup current interrupt lockout posture. */
;
MRS r3, CPSR ; Pickup current CPSR
BIC r1, r3, #INT_MASK ; Clear interrupt lockout bits
ORR r1, r1, r0 ; Or-in new interrupt lockout bits
;
; /* Apply the new interrupt posture. */
;
MSR CPSR_cxsf, r1 ; Setup new CPSR
AND r0, r3, #INT_MASK ; Return previous interrupt mask
BX lr ; Return to caller
;
;}
;
;
END

View File

@@ -0,0 +1,81 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
DISABLE_INTS DEFINE 0x80 ; IRQ interrupts disabled
;
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_interrupt_disable Cortex-R4/IAR */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
;/* */
;/**************************************************************************/
;UINT _tx_thread_interrupt_disable(VOID)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_interrupt_disable
ARM
_tx_thread_interrupt_disable??rA
_tx_thread_interrupt_disable
;
; /* Pickup current interrupt lockout posture. */
;
MRS r0, CPSR ; Pickup current CPSR
CPSID i ; Mask interrupts
BX lr ; Return to caller
;}
;
;
END

View File

@@ -0,0 +1,76 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_interrupt_restore Cortex-R4/IAR */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
;/* */
;/**************************************************************************/
;void _tx_thread_interrupt_restore(UINT old_posture)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_interrupt_restore
ARM
_tx_thread_interrupt_restore
;
; /* Apply the new interrupt posture. */
;
MSR CPSR_cxsf, r0 ; Setup new CPSR
BX lr ; Return to caller
;}
;
END

View File

@@ -0,0 +1,89 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
IRQ_MODE DEFINE 0x12 ; IRQ mode
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_irq_nesting_end Cortex-R4/IAR */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _tx_thread_irq_nesting_end(VOID)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_irq_nesting_end
ARM
_tx_thread_irq_nesting_end
MOV r3, lr ; Save ISR return address
CPSID i ; Disable interrupts
POP {lr} ; Pickup saved lr
CPS #IRQ_MODE ; Switch to IRQ mode
MOV pc, r3 ; Return to ISR
;}
;
;
END

View File

@@ -0,0 +1,86 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
SYS_MODE DEFINE 0x1F ; System mode
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_irq_nesting_start Cortex-R4/IAR */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _tx_thread_irq_nesting_start(VOID)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_irq_nesting_start
ARM
_tx_thread_irq_nesting_start
MOV r3, lr ; Save ISR return address
CPS #SYS_MODE ; Enter SYS mode
PUSH {lr} ; Save system mode lr on the system mode stack
CPSIE i ; Enable interrupts
MOV pc, r3 ; Return to ISR
;}
;
;
END

View File

@@ -0,0 +1,443 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
EXTERN _tx_thread_execute_ptr
EXTERN _tx_thread_current_ptr
EXTERN _tx_timer_time_slice
EXTERN _tx_execution_thread_enter
;
IMPORT _txm_system_mode_enter
IMPORT _txm_system_mode_exit
;
THUMB_MASK EQU 0x20 ; Thumb bit (5) of CPSR/SPSR.
IRQ_MODE EQU 0x12 ; IRQ mode
USR_MODE EQU 0x10 ; USR mode
SVC_MODE EQU 0x13 ; SVC mode
SYS_MODE EQU 0x1F ; SYS mode
MODE_MASK EQU 0x1F ; Mode mask
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_schedule Cortex-R4/MPU/IAR */
;/* 6.1 */
;/* AUTHOR */
;/* */
;/* Scott Larson, 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 */
;/* */
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _tx_thread_schedule(VOID)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_schedule
ARM
_tx_thread_schedule??rA
_tx_thread_schedule
; Enter the scheduler.
SVC 0
; We should never get here - ever!
_tx_scheduler_fault__
B _tx_scheduler_fault__
;}
; ****************************************************************************
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SWI_Handler
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RSEG .text:CODE:NOROOT(2)
PUBLIC SWI_Handler
ARM
SWI_Handler
STMFD sp!, {r0-r3, r12, lr} ; Store the registers
MOV r1, sp ; Set pointer to parameters
MRS r0, spsr ; Get spsr
STMFD sp!, {r0, r3} ; Store spsr onto stack and another
; register to maintain 8-byte-aligned stack
TST r0, #THUMB_MASK ; Occurred in Thumb state?
LDRNEH r0, [lr,#-2] ; Yes: Load halfword and...
BICNE r0, r0, #0xFF00 ; ...extract comment field
LDREQ r0, [lr,#-4] ; No: Load word and...
BICEQ r0, r0, #0xFF000000 ; ...extract comment field
; r0 now contains SVC number
; r1 now contains pointer to stacked registers
;
; The service call is handled here
;
CMP r0, #0 ; Is it a schedule request?
BEQ _tx_handler_svc_schedule ; Yes, go there
CMP r0, #1 ; Is it a system mode enter request?
BEQ _tx_handler_svc_super_enter ; Yes, go there
CMP r0, #2 ; Is it a system mode exit request?
BEQ _tx_handler_svc_super_exit ; Yes, go there
LDR r2, =0x123456
CMP r0, r2 ; Is it an ARM request?
BEQ _tx_handler_svc_arm ; Yes, go there
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Unknown SVC argument
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Unrecognized service call
_tx_handler_svc_unrecognized
_tx_handler_svc_unrecognized_loop ; We should never get here
B _tx_handler_svc_unrecognized_loop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SVC 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; At this point we have an SVC 1, which means we are entering
; supervisor mode to service a kernel call.
_tx_handler_svc_super_enter
; Make sure that we have been called from the system mode enter location (security)
LDR r2, =_txm_system_mode_enter ; Load the address of the known call point
SUB r1, lr, #4 ; Calculate the address of the actual call
CMP r1, r2 ; Did we come from txm_module_manager_user_mode_entry?
BNE _tx_handler_svc_unrecognized ; Return to where we came
; Clear the user mode flag in the thread structure
LDR r1, =_tx_thread_current_ptr ; Load the current thread pointer address
LDR r2, [r1] ; Load current thread location from the pointer (pointer indirection)
MOV r1, #0 ; Load the new user mode flag value (user mode flag clear -> not user mode -> system)
STR r1, [r2, #0x9C] ; Clear the current user mode selection for thread
; Now we enter the system mode and return
LDMFD sp!, {r0, r3} ; Get spsr from the stack
BIC r0, r0, #MODE_MASK ; clear mode field
ORR r0, r0, #SYS_MODE ; system mode code
MSR SPSR_cxsf, r0 ; Restore the spsr
LDR r1, [r2, #0xA8] ; Load the module kernel stack pointer
CPS #SYS_MODE ; Switch to SYS mode
MOV r3, sp ; Grab thread stack pointer
MOV sp, r1 ; Set SP to kernel stack pointer
CPS #SVC_MODE ; Switch back to SVC mode
STR r3, [r2, #0xB0] ; Save thread stack pointer
#ifndef TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE
LDR r3, [r2, #0xAC] ; Load the module kernel stack size
STR r3, [r2, #20] ; Set stack size
LDRD r0, r1, [r2, #0xA4] ; Load the module kernel stack start and end
STRD r0, r1, [r2, #0x0C] ; Set stack start and end
#endif
LDMFD sp!, {r0-r3, r12, pc}^ ; Restore the registers and return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SVC 2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; At this point we have an SVC 2, which means we are exiting
; supervisor mode after servicing a kernel call.
_tx_handler_svc_super_exit
; Make sure that we have been called from the system mode exit location (security)
LDR r2, =_txm_system_mode_exit ; Load the address of the known call point
SUB r1, lr, #4 ; Calculate the address of the actual call
CMP r1, r2 ; Did we come from txm_module_manager_user_mode_entry?
BNE _tx_handler_svc_unrecognized ; Return to where we came
; Set the user mode flag into the thread structure
LDR r1, =_tx_thread_current_ptr ; Load the current thread pointer address
LDR r2, [r1] ; Load the current thread location from the pointer (pointer indirection)
MOV r1, #1 ; Load the new user mode flag value (user mode enabled -> not system anymore)
STR r1, [r2, #0x9C] ; Clear the current user mode selection for thread
; Now we enter user mode (exit the system mode) and return
LDMFD sp!, {r0, r3} ; Get spsr from the stack
BIC r0, r0, #MODE_MASK ; clear mode field
ORR r0, r0, #USR_MODE ; user mode code
MSR SPSR_cxsf, r0 ; Restore the spsr
LDR r1, [r2, #0xB0] ; Load the module thread stack pointer
CPS #SYS_MODE ; Switch to SYS mode
MOV sp, r1 ; Set SP back to thread stack pointer
CPS #SVC_MODE ; Switch back to SVC mode
#ifndef TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE
LDR r3, [r2, #0xBC] ; Load the module thread stack size
STR r3, [r2, #20] ; Set stack size
LDRD r0, r1, [r2, #0xB4] ; Load the module thread stack start and end
STRD r0, r1, [r2, #0x0C] ; Set stack start and end
#endif
LDMFD sp!, {r0-r3, r12, pc}^ ; Restore the registers and return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ARM Semihosting
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_tx_handler_svc_arm
; *** TODO: handle semihosting requests or ARM angel requests ***
; just return
LDMFD sp!, {r0, r3} ; Get spsr from the stack
MSR SPSR_cxsf, r0 ; Restore the spsr
LDMFD sp!, {r0-r3, r12, pc}^ ; Restore the registers and return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SVC 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; At this point we have an SVC 0: enter the scheduler.
_tx_handler_svc_schedule
LDMFD sp!, {r0, r3} ; Get spsr from stack
MSR SPSR_cxsf, r0 ; Restore spsr
LDMFD sp!, {r0-r3, r12, lr} ; Restore the registers
; This code 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.
;
; /* Enable interrupts. */
;
CPSIE i ; Enable IRQ interrupts
;
; /* 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, #0] ; 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. */
;
CPSID i ; Disable interrupts
;
; /* 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, #0] ; 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
STR r3, [r2, #0] ; Setup time-slice
;
#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.
CPS #SYS_MODE ; Enter SYS mode
LDR sp, [r0, #8] ; Switch to thread stack pointer
LDMIA sp!, {r4, r5} ; Pickup the stack type and saved CPSR
CPS #SVC_MODE ; Enter SVC mode
; **************************************************************************
; Set up MPU for module.
LDR r1, [r0, #0x94] ; Pickup module instance pointer
CMP r1, #0 ; Valid module pointer?
BEQ _tx_end_mpu_update ; No - skip memory protection setup
LDR r2, [r0, #0xA0] ; Pickup tx_thread_module_user_mode
CMP r2, #1 ; In user mode?
BNE _tx_end_mpu_update ; No - skip memory protection setup
; Is the MPU already set up for this module?
; Pickup the first data entry to check (txm_module_instance_mpu_registers[5])
LDR r2, [r1, #0xA0] ; Pickup txm_module_instance_mpu_registers[5]
MOV r3, #5 ; Select region 5
MCR p15, 0, r3, c6, c2, 0 ; Select region 5
MRC p15, 0, r3, c6, c1, 0 ; Read DRBAR into r3
CMP r2, r3 ; Is module already loaded?
BEQ _tx_end_mpu_update ; Yes - skip memory protection setup
; Disable MPU before applying new regions.
MRC p15, 0, r2, c1, c0, 0 ; Read SCTLR
BIC r2, r2, #1 ; Disable MPU
DSB
MCR p15, 0, r2, c1, c0, 0 ; Write to SCTLR
ISB
; Loop to load MPU registers
MOV r3, #0 ; Loop index
ADD r1, r1, #0x64 ; Build address of MPU register table
_tx_mpu_loop
LDR r2, [r1] ; Pickup txm_module_mpu_region_address
MCR p15, 0, r3, c6, c2, 0 ; Select region
MCR p15, 0, r2, c6, c1, 0 ; Write to DRBAR
ADD r1, r1, #4 ; Increment to next MPU parameter
LDR r2, [r1] ; Pickup txm_module_mpu_region_size
MCR p15, 0, r2, c6, c1, 2 ; Write to DRSR
ADD r1, r1, #4 ; Increment to next MPU parameter
LDR r2, [r1] ; Pickup txm_module_mpu_region_attributes
MCR p15, 0, r2, c6, c1, 4 ; Write to DRACR
ADD r1, r1, #4 ; Increment to next MPU parameter
ADD r3, r3, #1 ; Increment loop index
CMP r3, #0xB ; Check the limit
BLE _tx_mpu_loop ; Loop if not finished
; Enable MPU with new regions.
MRC p15, 0, r2, c1, c0, 0 ; Read SCTLR
ORR r2, r2, #1 ; Enable MPU
ORR r2, r2, #0x20000 ; Enable Background Region
DSB
MCR p15, 0, r2, c1, c0, 0 ; Write to SCTLR
ISB
;
_tx_end_mpu_update
; **************************************************************************
CMP r4, #0 ; Check for synchronous context switch
BEQ _tx_solicited_return
MSR SPSR_cxsf, r5 ; Setup SPSR for return
LDR r1, [r0, #8] ; Get thread SP
LDR lr, [r1, #0x40] ; Get thread PC
CPS #SYS_MODE ; Enter SYS mode
#ifdef __ARMVFP__
LDR r2, [r0, #144] ; Pickup the VFP enabled flag
CMP r2, #0 ; Is the VFP enabled?
BEQ _tx_skip_interrupt_vfp_restore ; No, skip VFP interrupt restore
VLDMIA sp!, {D0-D15} ; Recover D0-D15
LDR r4, [sp], #4 ; Pickup FPSCR
VMSR FPSCR, r4 ; Restore FPSCR
CPS #SVC_MODE ; Enter SVC mode
LDR lr, [r1, #0x144] ; Get thread PC
CPS #SYS_MODE ; Enter SYS mode
_tx_skip_interrupt_vfp_restore
#endif
LDMIA sp!, {r0-r12, lr} ; Restore registers
ADD sp, sp, #4 ; Fix stack pointer
CPS #SVC_MODE ; Enter SVC mode
SUBS pc, lr, #0 ; Return to point of thread interrupt
_tx_solicited_return
MOV r2, r5 ; Move CPSR to scratch register
CPS #SYS_MODE ; Enter SYS mode
#ifdef __ARMVFP__
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
LDR r4, [sp], #4 ; Pickup FPSCR
VMSR FPSCR, r4 ; Restore FPSCR
_tx_skip_solicited_vfp_restore
#endif
LDMIA sp!, {r4-r11, lr} ; Restore registers
MOV r1, lr ; Copy lr to r1 to preserve across mode change
CPS #SVC_MODE ; Enter SVC mode
MSR SPSR_cxsf, r2 ; Recover CPSR
SUBS pc, r1, #0 ; Return to thread synchronously
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; End SWI_Handler
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#ifdef __ARMVFP__
PUBLIC tx_thread_vfp_enable
CODE32
tx_thread_vfp_enable??rA
tx_thread_vfp_enable
MRS r2, CPSR ; Pickup the CPSR
CPSID i ; Disable IRQ interrupts
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
PUBLIC tx_thread_vfp_disable
CODE32
tx_thread_vfp_disable??rA
tx_thread_vfp_disable
MRS r2, CPSR ; Pickup the CPSR
CPSID i ; Disable IRQ interrupts
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
END

View File

@@ -0,0 +1,142 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
SYS_MODE DEFINE 0x1F ; SYS mode
CPSR_MASK DEFINE 0x9F ; Mask initial CPSR, IRQ ints enabled
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_stack_build Cortex-R4/MPU/IAR */
;/* 6.1 */
;/* AUTHOR */
;/* */
;/* Scott Larson, 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 */
;/* */
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_stack_build
ARM
_tx_thread_stack_build
;
;
; /* Build a fake interrupt frame. The form of the fake interrupt stack
; on the Cortex-R4 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)
MOV r3, #0 ; Build initial register value
STR r3, [r2, #52] ; Store initial r11
STR r3, [r2, #56] ; Store initial r12
STR r3, [r2, #60] ; Store initial lr
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, #SYS_MODE ; Build CPSR, SYS 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
BX lr ; Return to caller
;}
END

View File

@@ -0,0 +1,145 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
EXTERN _tx_thread_current_ptr
EXTERN _tx_timer_time_slice
EXTERN _tx_thread_schedule
EXTERN _tx_execution_thread_exit
;
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_system_return Cortex-R4/IAR */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _tx_thread_system_return(VOID)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_system_return
ARM
_tx_thread_system_return??rA
_tx_thread_system_return
;
; /* Lockout interrupts. */
;
MRS r1, CPSR ; Pickup the CPSR
CPSID i ; Disable interrupts
; /* Save minimal context on the stack. */
;
STMDB sp!, {r4-r11, lr} ; Save minimal context
LDR r5, =_tx_thread_current_ptr ; Pickup address of current ptr
LDR r6, [r5, #0] ; Pickup current thread pointer
#ifdef __ARMVFP__
LDR r0, [r6, #144] ; Pickup the VFP enabled flag
CMP r0, #0 ; Is the VFP enabled?
BEQ _tx_skip_solicited_vfp_save ; No, skip VFP solicited save
VMRS r4, FPSCR ; Pickup the FPSCR
STR r4, [sp, #-4]! ; Save FPSCR
VSTMDB sp!, {D8-D15} ; Save D8-D15
_tx_skip_solicited_vfp_save:
#endif
MOV r0, #0 ; Build a solicited stack type
STMDB sp!, {r0-r1} ; Save type and CPSR
;
;
#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
LDR r2, =_tx_timer_time_slice ; Pickup address of time slice
LDR r1, [r2, #0] ; 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, [r6, #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, #0] ; Clear time-slice
STR r1, [r6, #24] ; Save current time-slice
;
; }
__tx_thread_dont_save_ts
;
; /* Clear the current thread pointer. */
; _tx_thread_current_ptr = TX_NULL;
;
STR r4, [r5, #0] ; Clear current thread pointer
B _tx_thread_schedule ; Jump to scheduler!
;
;}
END

View File

@@ -0,0 +1,174 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
EXTERN _tx_thread_system_state
EXTERN _tx_thread_current_ptr
EXTERN _tx_execution_isr_enter
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_vectored_context_save Cortex-R4/IAR */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _tx_thread_vectored_context_save(VOID)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_vectored_context_save
ARM
_tx_thread_vectored_context_save
;
; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
; out, we are in IRQ mode, the minimal context is already saved, and the
; lr register contains the return ISR address. */
;
; /* Check for a nested interrupt condition. */
; if (_tx_thread_system_state++)
; {
;
LDR r3, =_tx_thread_system_state ; Pickup address of system state var
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
BX 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 occured 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_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
BX 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
;
; }
;}
END

View File

@@ -0,0 +1,247 @@
;/**************************************************************************/
;/* */
;/* 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 Assembly language external references...
;
EXTERN _tx_timer_time_slice
EXTERN _tx_timer_system_clock
EXTERN _tx_timer_current_ptr
EXTERN _tx_timer_list_start
EXTERN _tx_timer_list_end
EXTERN _tx_timer_expired_time_slice
EXTERN _tx_timer_expired
EXTERN _tx_thread_time_slice
EXTERN _tx_timer_expiration_process
;
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_timer_interrupt Cortex-R4/IAR */
;/* 6.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_timer_expiration_process Timer expiration processing */
;/* _tx_thread_time_slice Time-slice interrupted thread */
;/* */
;/* CALLED BY */
;/* */
;/* interrupt vector */
;/* */
;/* RELEASE HISTORY */
;/* */
;/* DATE NAME DESCRIPTION */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _tx_timer_interrupt(VOID)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_timer_interrupt
ARM
_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, #0] ; Pickup system clock
ADD r0, r0, #1 ; Increment system clock
STR r0, [r1, #0] ; 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, #0] ; 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, #0] ; 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, #0] ; 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 addr
LDR r0, [r1, #0] ; Pickup current timer
LDR r2, [r0, #0] ; 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, #0] ; 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 wrap-around. */
; if (_tx_timer_current_ptr == _tx_timer_list_end)
;
LDR r3, =_tx_timer_list_end ; Pickup addr of timer list end
LDR r2, [r3, #0] ; Pickup list end
CMP r0, r2 ; Are we at list end?
BNE __tx_timer_skip_wrap ; No, skip wrap-around logic
;
; /* Wrap to beginning of list. */
; _tx_timer_current_ptr = _tx_timer_list_start;
;
LDR r3, =_tx_timer_list_start ; Pickup addr of timer list start
LDR r0, [r3, #0] ; Set current pointer to list start
;
__tx_timer_skip_wrap
;
STR r0, [r1, #0] ; 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 addr of expired flag
LDR r2, [r3, #0] ; 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 addr of other expired flag
LDR r0, [r1, #0] ; 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 addr of expired flag
LDR r0, [r1, #0] ; 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 addr of time-slice expired
LDR r2, [r3, #0] ; 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
;
BX lr ; Return to caller
;
;}
END

View File

@@ -0,0 +1,188 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_power_of_two_block_size Cortex-R4/MPU/IAR */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function calculates a power of two size at or immediately above*/
/* the input size and returns it to the caller. */
/* */
/* INPUT */
/* */
/* size Block size */
/* */
/* OUTPUT */
/* */
/* calculated size Rounded up to power of two */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_alignment_adjust Adjust alignment for Cortex-R */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
ULONG _txm_power_of_two_block_size(ULONG size)
{
/* Check for 0 size. */
if(size == 0)
return 0;
/* Minimum MPU block size is 32. */
if(size <= 32)
return 32;
/* Bit twiddling trick to round to next high power of 2
(if original size is power of 2, it will return original size. Perfect!) */
size--;
size |= size >> 1;
size |= size >> 2;
size |= size >> 4;
size |= size >> 8;
size |= size >> 16;
size++;
/* Return a power of 2 size at or above the input size. */
return(size);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_alignment_adjust Cortex-R4/MPU/IAR */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function adjusts the alignment and size of the code and data */
/* section for a given module implementation. */
/* */
/* INPUT */
/* */
/* module_preamble Pointer to module preamble */
/* code_size Size of the code area (updated) */
/* code_alignment Code area alignment (updated) */
/* data_size Size of data area (updated) */
/* data_alignment Data area alignment (updated) */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _txm_power_of_two_block_size Calculate power of two size */
/* */
/* CALLED BY */
/* */
/* Initial thread stack frame */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble,
ULONG *code_size,
ULONG *code_alignment,
ULONG *data_size,
ULONG *data_alignment)
{
ULONG local_code_size;
ULONG local_code_alignment;
ULONG local_data_size;
ULONG local_data_alignment;
ULONG code_size_accum;
ULONG data_size_accum;
/* Copy the input parameters into local variables for ease of use. */
local_code_size = *code_size;
local_code_alignment = *code_alignment;
local_data_size = *data_size;
local_data_alignment = *data_alignment;
/* Determine code block sizes. Minimize the alignment requirement.
There are 4 MPU code entries available. The following is how the code size
will be distributed:
1. 1/4 of the largest power of two that is greater than or equal to code size.
2. 1/4 of the largest power of two that is greater than or equal to code size.
3. Largest power of 2 that fits in the remaining space.
4. Smallest power of 2 that exceeds the remaining space, minimum 32. */
local_code_alignment = _txm_power_of_two_block_size(local_code_size) >> 2;
code_size_accum = local_code_alignment + local_code_alignment;
code_size_accum = code_size_accum + (_txm_power_of_two_block_size(local_code_size - code_size_accum) >> 1);
code_size_accum = code_size_accum + _txm_power_of_two_block_size(local_code_size - code_size_accum);
local_code_size = code_size_accum;
/* Determine data block sizes. Minimize the alignment requirement.
There are 4 MPU data entries available. The following is how the data size
will be distributed:
1. 1/4 of the largest power of two that is greater than or equal to data size.
2. 1/4 of the largest power of two that is greater than or equal to data size.
3. Largest power of 2 that fits in the remaining space.
4. Smallest power of 2 that exceeds the remaining space, minimum 32. */
local_data_alignment = _txm_power_of_two_block_size(local_data_size) >> 2;
data_size_accum = local_data_alignment + local_data_alignment;
data_size_accum = data_size_accum + (_txm_power_of_two_block_size(local_data_size - data_size_accum) >> 1);
data_size_accum = data_size_accum + _txm_power_of_two_block_size(local_data_size - data_size_accum);
local_data_size = data_size_accum;
/* Return all the information to the caller. */
*code_size = local_code_size;
*code_alignment = local_code_alignment;
*data_size = local_data_size;
*data_alignment = local_data_alignment;
}

View 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 */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_mutex.h"
#include "tx_queue.h"
#include "tx_thread.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_external_memory_enable Cortex-R4/MPU/IAR */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function adds an entry in the MPU table for a shared */
/* memory space. */
/* */
/* INPUT */
/* */
/* module_instance Module instance pointer */
/* start_address Start address of memory */
/* length Length of external memory */
/* attributes Memory attributes (r/w) */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _tx_mutex_get Get protection mutex */
/* _tx_mutex_put Release protection mutex */
/* _txm_power_of_two_block_size Round length to power of two */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_external_memory_enable(TXM_MODULE_INSTANCE *module_instance,
VOID *start_address,
ULONG length,
UINT attributes)
{
ULONG block_size;
ULONG region_size;
ULONG srd_bits;
ULONG size_register;
ULONG address;
ULONG shared_index;
ULONG attributes_check = 0;
/* Determine if the module manager has been initialized. */
if (_txm_module_manager_ready != TX_TRUE)
{
/* Module manager has not been initialized. */
return(TX_NOT_AVAILABLE);
}
/* Determine if the module is valid. */
if (module_instance == TX_NULL)
{
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Get module manager protection mutex. */
_tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER);
/* Determine if the module instance is valid. */
if (module_instance -> txm_module_instance_id != TXM_MODULE_ID)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Determine if the module instance is in the loaded state. */
if (module_instance -> txm_module_instance_state != TXM_MODULE_LOADED)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return error if the module is not ready. */
return(TX_START_ERROR);
}
/* Determine if there are shared memory entries available. */
if(module_instance -> txm_module_instance_shared_memory_count >= TXM_MODULE_MPU_SHARED_ENTRIES)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* No more entries available. */
return(TX_NO_MEMORY);
}
/* Start address and length must adhere to Cortex-R MPU.
The address must align with the block size. */
block_size = _txm_power_of_two_block_size(length);
address = (ULONG) start_address;
if(address != (address & ~(block_size - 1)))
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return alignment error. */
return(TXM_MODULE_ALIGNMENT_ERROR);
}
/* At this point, we have a valid address and block size.
Set up MPU registers. */
/* Generate index into shared memory entries. */
shared_index = TXM_MODULE_MPU_SHARED_INDEX + module_instance -> txm_module_instance_shared_memory_count;
/* Save address register. */
module_instance -> txm_module_instance_mpu_registers[shared_index].txm_module_mpu_region_address = address;
/* Calculate the region size. */
region_size = (_txm_module_manager_region_size_get(block_size) << 1);
/* Calculate the subregion bits. */
srd_bits = _txm_module_manager_calculate_srd_bits(block_size, length);
/* Save size register. */
size_register = srd_bits | region_size | TXM_ENABLE_REGION;
module_instance -> txm_module_instance_mpu_registers[shared_index].txm_module_mpu_region_size = size_register;
/* Check for optional attributes. */
if(attributes & TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE)
{
attributes_check = TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT;
}
/* Save attributes register. */
module_instance -> txm_module_instance_mpu_registers[shared_index].txm_module_mpu_region_attributes = attributes_check | TXM_MODULE_MPU_SHARED_ACCESS_CONTROL;
/* Keep track of shared memory address and length in module instance. */
module_instance -> txm_module_instance_shared_memory_address[module_instance -> txm_module_instance_shared_memory_count] = address;
module_instance -> txm_module_instance_shared_memory_length[module_instance -> txm_module_instance_shared_memory_count] = length;
/* Increment counter. */
module_instance -> txm_module_instance_shared_memory_count++;
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return success. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,112 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_thread.h"
#include "txm_module.h"
/* Define the user's fault notification callback function pointer. This is
setup via the txm_module_manager_memory_fault_notify API. */
VOID (*_txm_module_manager_fault_notify)(TX_THREAD *, TXM_MODULE_INSTANCE *);
/* Define a macro that can be used to allocate global variables useful to
store information about the last fault. This macro is defined in
txm_module_port.h and is usually populated in the assembly language
fault handling prior to the code calling _txm_module_manager_memory_fault_handler. */
TXM_MODULE_MANAGER_FAULT_INFO
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_memory_fault_handler Cortex-R4/MPU/IAR */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles a fault associated with a memory protected */
/* module. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_terminate Terminate thread */
/* */
/* CALLED BY */
/* */
/* Fault handler */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_memory_fault_handler(VOID)
{
TXM_MODULE_INSTANCE *module_instance_ptr;
TX_THREAD *thread_ptr;
/* Pickup the current thread. */
thread_ptr = _tx_thread_current_ptr;
/* Initialize the module instance pointer to NULL. */
module_instance_ptr = TX_NULL;
/* Is there a thread? */
if (thread_ptr)
{
/* Pickup the module instance. */
module_instance_ptr = thread_ptr -> tx_thread_module_instance_ptr;
/* Terminate the current thread. */
_tx_thread_terminate(_tx_thread_current_ptr);
}
/* Determine if there is a user memory fault notification callback. */
if (_txm_module_manager_fault_notify)
{
/* Yes, call the user's notification memory fault callback. */
(_txm_module_manager_fault_notify)(thread_ptr, module_instance_ptr);
}
}

View File

@@ -0,0 +1,84 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_thread.h"
#include "txm_module.h"
/* Define the external user's fault notification callback function pointer. This is
setup via the txm_module_manager_memory_fault_notify API. */
extern VOID (*_txm_module_manager_fault_notify)(TX_THREAD *, TXM_MODULE_INSTANCE *);
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_memory_fault_notify Cortex-R4/MPU/IAR */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function registers an application callback when/if a memory */
/* fault occurs. The supplied thread is automatically terminated, but */
/* any other threads in the same module may still execute. */
/* */
/* INPUT */
/* */
/* notify_function Memory fault notification */
/* function, NULL disables. */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_memory_fault_notify(VOID (*notify_function)(TX_THREAD *, TXM_MODULE_INSTANCE *))
{
/* Setup notification function. */
_txm_module_manager_fault_notify = notify_function;
/* Return success. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,543 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_region_size_get Cortex-R4/MPU/IAR */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function converts the region size in bytes to the block size */
/* for the Cortex-R4 MPU specification. */
/* */
/* INPUT */
/* */
/* block_size Size of the block in bytes */
/* */
/* OUTPUT */
/* */
/* MPU size specification */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_mm_register_setup */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
ULONG _txm_module_manager_region_size_get(ULONG block_size)
{
ULONG return_value;
/* Process relative to the input block size. */
if (block_size == 32)
{
return_value = 0x04;
}
else if (block_size == 64)
{
return_value = 0x05;
}
else if (block_size == 128)
{
return_value = 0x06;
}
else if (block_size == 256)
{
return_value = 0x07;
}
else if (block_size == 512)
{
return_value = 0x08;
}
else if (block_size == 1024)
{
return_value = 0x09;
}
else if (block_size == 2048)
{
return_value = 0x0A;
}
else if (block_size == 4096)
{
return_value = 0x0B;
}
else if (block_size == 8192)
{
return_value = 0x0C;
}
else if (block_size == 16384)
{
return_value = 0x0D;
}
else if (block_size == 32768)
{
return_value = 0x0E;
}
else if (block_size == 65536)
{
return_value = 0x0F;
}
else if (block_size == 131072)
{
return_value = 0x10;
}
else if (block_size == 262144)
{
return_value = 0x11;
}
else if (block_size == 524288)
{
return_value = 0x12;
}
else if (block_size == 1048576)
{
return_value = 0x13;
}
else if (block_size == 2097152)
{
return_value = 0x14;
}
else
{
/* Max 4MB MPU pages for modules. */
return_value = 0x15;
}
return(return_value);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_calculate_srd_bits Cortex-R4/MPU/IAR */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function calculates the SRD bits that need to be set to */
/* protect "length" bytes in a block. */
/* */
/* INPUT */
/* */
/* block_size Size of the block in bytes */
/* length Actual length in bytes */
/* */
/* OUTPUT */
/* */
/* SRD bits to be OR'ed with region attribute register. */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_mm_register_setup */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
ULONG _txm_module_manager_calculate_srd_bits(ULONG block_size, ULONG length)
{
ULONG srd_bits = 0;
UINT srd_bit_index;
/* length is smaller than block_size, set SRD bits if block_size is 256 or more. */
if((block_size >= 256) && (length < block_size))
{
/* Divide block_size by 8 by shifting right 3. Result is size of subregion. */
block_size = block_size >> 3;
/* Set SRD index into attribute register. */
srd_bit_index = 8;
/* If subregion overlaps length, move to the next subregion. */
while(length > block_size)
{
length = length - block_size;
srd_bit_index++;
}
/* Check for a portion of code remaining. */
if(length)
{
srd_bit_index++;
}
/* Set unused subregion bits. */
while(srd_bit_index < 16)
{
srd_bits = srd_bits | (0x1 << srd_bit_index);
srd_bit_index++;
}
}
return(srd_bits);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_register_setup Cortex-R4/MPU/IAR */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sets up the MPU register definitions based on the */
/* module's memory characteristics. */
/* MPU layout for the Cortex-R4: */
/* Entry Description */
/* 0 Kernel mode entry */
/* 1 Module code region */
/* 2 Module code region */
/* 3 Module code region */
/* 4 Module code region */
/* 5 Module data region */
/* 6 Module data region */
/* 7 Module data region */
/* 8 Module data region */
/* 9 Module shared memory region */
/* 10 Module shared memory region */
/* 11 Module shared memory region */
/* */
/* */
/* INPUT */
/* */
/* module_instance Pointer to module instance */
/* */
/* OUTPUT */
/* */
/* MPU specifications for module in module_instance */
/* */
/* CALLS */
/* */
/* _txm_module_manager_region_size_get */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_thread_create */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
{
ULONG code_address;
ULONG code_size;
ULONG data_address;
ULONG data_size;
ULONG start_stop_stack_size;
ULONG callback_stack_size;
ULONG block_size;
ULONG base_address_register;
ULONG size_register;
ULONG region_size;
ULONG srd_bits = 0;
UINT mpu_table_index;
UINT i;
/* Setup the first region for kernel mode entry. */
/* Set address register to user mode entry function address, which is guaranteed to be at least 32-byte aligned. */
module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MPU_KERNEL_ENTRY_INDEX].txm_module_mpu_region_address = (ULONG) _txm_module_manager_user_mode_entry;
/* Set the size (32 bytes) and enable bit. */
module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MPU_KERNEL_ENTRY_INDEX].txm_module_mpu_region_size = (_txm_module_manager_region_size_get(32) << 1) | TXM_ENABLE_REGION;
/* Set attributes. */
module_instance -> txm_module_instance_mpu_registers[TXM_MODULE_MPU_KERNEL_ENTRY_INDEX].txm_module_mpu_region_attributes = TXM_MODULE_MPU_CODE_ACCESS_CONTROL;
/* End of kernel mode entry setup. */
/* Setup code protection. */
/* Initialize the MPU table index. */
mpu_table_index = 1;
/* Pickup code starting address and actual size. */
code_address = (ULONG) module_instance -> txm_module_instance_code_start;
code_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_code_size;
/* Determine code block sizes. Minimize the alignment requirement.
There are 4 MPU code entries available. The following is how the code size
will be distributed:
1. 1/4 of the largest power of two that is greater than or equal to code size.
2. 1/4 of the largest power of two that is greater than or equal to code size.
3. Largest power of 2 that fits in the remaining space.
4. Smallest power of 2 that exceeds the remaining space, minimum 32. */
/* Now loop through to setup MPU protection for the code area. */
for (i = 0; i < TXM_MODULE_MPU_CODE_ENTRIES; i++)
{
/* First two MPU blocks are 1/4 of the largest power of two
that is greater than or equal to code size. */
if (i < 2)
{
block_size = _txm_power_of_two_block_size(code_size) >> 2;
}
/* Third MPU block is the largest power of 2 that fits in the remaining space. */
else if (i == 2)
{
/* Subtract (block_size*2) from code_size to calculate remaining space. */
code_size = code_size - (block_size << 1);
block_size = _txm_power_of_two_block_size(code_size) >> 1;
}
/* Last MPU block is the smallest power of 2 that exceeds the remaining space, minimum 32. */
else
{
/* Calculate remaining space. */
code_size = code_size - block_size;
block_size = _txm_power_of_two_block_size(code_size);
srd_bits = _txm_module_manager_calculate_srd_bits(block_size, code_size);
}
/* Build the base address register. */
base_address_register = (code_address & ~(block_size - 1));
/* Calculate the region size information. */
region_size = (_txm_module_manager_region_size_get(block_size) << 1);
/* Build the size register. */
size_register = srd_bits | region_size | TXM_ENABLE_REGION;
/* Setup the MPU address, size, and attribute registers. */
module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = base_address_register;
module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_size = size_register;
module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_attributes = TXM_MODULE_MPU_CODE_ACCESS_CONTROL;
/* Adjust the code address. */
code_address = code_address + block_size;
/* Increment MPU table index. */
mpu_table_index++;
}
/* End of code protection. */
/* Setup data protection. */
/* Reset SRD bitfield. */
srd_bits = 0;
/* Pickup data starting address and actual size. */
data_address = (ULONG) module_instance -> txm_module_instance_data_start;
/* Adjust the size of the module elements to be aligned to the default alignment. We do this
so that when we partition the allocated memory, we can simply place these regions right beside
each other without having to align their pointers. Note this only works when they all have
the same alignment. */
data_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_data_size;
start_stop_stack_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_start_stop_stack_size;
callback_stack_size = module_instance -> txm_module_instance_preamble_ptr -> txm_module_preamble_callback_stack_size;
data_size = ((data_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT;
start_stop_stack_size = ((start_stop_stack_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT;
callback_stack_size = ((callback_stack_size + TXM_MODULE_DATA_ALIGNMENT - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT;
/* Update the data size to include thread stacks. */
data_size = data_size + start_stop_stack_size + callback_stack_size;
/* Determine data block sizes. Minimize the alignment requirement.
There are 4 MPU data entries available. The following is how the data size
will be distributed:
1. 1/4 of the largest power of two that is greater than or equal to data size.
2. 1/4 of the largest power of two that is greater than or equal to data size.
3. Largest power of 2 that fits in the remaining space.
4. Smallest power of 2 that exceeds the remaining space, minimum 32. */
/* Now loop through to setup MPU protection for the data area. */
for (i = 0; i < TXM_MODULE_MPU_DATA_ENTRIES; i++)
{
/* First two MPU blocks are 1/4 of the largest power of two
that is greater than or equal to data size. */
if (i < 2)
{
block_size = _txm_power_of_two_block_size(data_size) >> 2;
}
/* Third MPU block is the largest power of 2 that fits in the remaining space. */
else if (i == 2)
{
/* Subtract (block_size*2) from data_size to calculate remaining space. */
data_size = data_size - (block_size << 1);
block_size = _txm_power_of_two_block_size(data_size) >> 1;
}
/* Last MPU block is the smallest power of 2 that exceeds the remaining space, minimum 32. */
else
{
/* Calculate remaining space. */
data_size = data_size - block_size;
block_size = _txm_power_of_two_block_size(data_size);
srd_bits = _txm_module_manager_calculate_srd_bits(block_size, data_size);
}
/* Build the base address register. */
base_address_register = (data_address & ~(block_size - 1));
/* Calculate the region size information. */
region_size = (_txm_module_manager_region_size_get(block_size) << 1);
/* Build the size register. */
size_register = srd_bits | region_size | TXM_ENABLE_REGION;
/* Setup the MPU address, size, and attribute registers. */
module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = base_address_register;
module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_size = size_register;
module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_attributes = TXM_MODULE_MPU_DATA_ACCESS_CONTROL;
/* Adjust the data address. */
data_address = data_address + block_size;
/* Increment MPU table index. */
mpu_table_index++;
}
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_inside_data_check Cortex-R4/MPU/IAR */
/* 6.1.6 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function checks if the specified object is inside shared */
/* memory. */
/* */
/* INPUT */
/* */
/* module_instance Pointer to module instance */
/* obj_ptr Pointer to the object */
/* obj_size Size of the object */
/* */
/* OUTPUT */
/* */
/* Whether the object is inside the shared memory region. */
/* */
/* CALLS */
/* */
/* N/A */
/* */
/* CALLED BY */
/* */
/* Module dispatch check functions */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 04-02-2021 Scott Larson Modified comments, added */
/* check for overflow, *
/* resulting in version 6.1.6 */
/* */
/**************************************************************************/
UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE obj_ptr, UINT obj_size)
{
UINT shared_memory_index;
UINT num_shared_memory_mpu_entries;
ALIGN_TYPE shared_memory_address_start;
ALIGN_TYPE shared_memory_address_end;
/* Check for overflow. */
if ((obj_ptr) > ((obj_ptr) + (obj_size)))
{
return(TX_FALSE);
}
/* Check if the object is inside the module data. */
if ((obj_ptr >= (ALIGN_TYPE) module_instance -> txm_module_instance_data_start) &&
((obj_ptr + obj_size) <= ((ALIGN_TYPE) module_instance -> txm_module_instance_data_end + 1)))
{
return(TX_TRUE);
}
/* Check if the object is inside the shared memory. */
num_shared_memory_mpu_entries = module_instance -> txm_module_instance_shared_memory_count;
for (shared_memory_index = 0; shared_memory_index < num_shared_memory_mpu_entries; shared_memory_index++)
{
shared_memory_address_start = (ALIGN_TYPE) module_instance -> txm_module_instance_shared_memory_address[shared_memory_index];
shared_memory_address_end = shared_memory_address_start + module_instance -> txm_module_instance_shared_memory_length[shared_memory_index];
if ((obj_ptr >= (ALIGN_TYPE) shared_memory_address_start) &&
((obj_ptr + obj_size) <= (ALIGN_TYPE) shared_memory_address_end))
{
return(TX_TRUE);
}
}
return(TX_FALSE);
}

View File

@@ -0,0 +1,148 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
THUMB_MASK DEFINE 0x20 ; THUMB bit
USR_MODE DEFINE 0x10 ; USR mode
SYS_MODE DEFINE 0x1F ; SYS mode
CPSR_MASK DEFINE 0xBF ; Mask initial CPSR, IRQ ints enabled
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _txm_module_manager_thread_stack_build Cortex-R4/MPU/IAR */
;/* 6.1 */
;/* AUTHOR */
;/* */
;/* Scott Larson, 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 */
;/* */
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _txm_module_manager_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(TX_THREAD *, TXM_MODULE_INSTANCE *))
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _txm_module_manager_thread_stack_build
ARM
_txm_module_manager_thread_stack_build
;
;
; /* Build a fake interrupt frame. The form of the fake interrupt stack
; on the Cortex-R4 should look like the following after it is built:
;
; Stack Top: 1 Interrupt stack frame type
; CPSR Initial value for CPSR
; r0 Initial value for r0
; r1 Initial value for r1
; r2 Initial value for r2
; r3 Initial value for r3
; r4 Initial value for r4
; r5 Initial value for r5
; r6 Initial value for r6
; r7 Initial value for r7
; r8 Initial value for r8
; r9 Initial value for r9
; r10 Initial value for r10
; r11 Initial value for r11
; r12 Initial value for r12
; lr Initial value for lr (r14)
; pc Initial value for pc (r15)
; 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
STR r0, [r2, #8] ; Store initial r0 (thread pointer)
LDR r3, [r0, #8] ; Pickup thread info pointer (it's in the stack pointer location right now)
STR r3, [r2, #12] ; Store initial r1
LDR r3, [r3, #8] ; Pickup data base register
STR r3, [r2, #44] ; Store initial r9
MOV r3, #0 ; Build initial register value
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
LDR r3, [r0, #12] ; Pickup stack starting address
STR r3, [r2, #48] ; Store initial r10 (sl)
MOV r3, #0 ; Build initial register value
STR r3, [r2, #52] ; Store initial r11
STR r3, [r2, #56] ; Store initial r12
STR r3, [r2, #60] ; Store initial lr
STR r1, [r2, #64] ; Store initial pc
STR r3, [r2, #68] ; 0 for back-trace
MRS r3, CPSR ; Pickup CPSR
BIC r3, r3, #CPSR_MASK ; Mask mode bits of CPSR
TST r1, #1 ; Test if THUMB bit set in initial PC
ORRNE r3, r3, #THUMB_MASK ; Set T bit if set
LDR r1, [r0, #156] ; Load tx_thread_module_user_mode
TST r1, #1 ; Test if the user mode flag is set
ORREQ r3, r3, #SYS_MODE ; Flag not set: Build CPSR, SYS mode, IRQ enabled
ORRNE r3, r3, #USR_MODE ; Flag set: Build CPSR, USR mode, IRQ 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
BX lr ; Return to caller
;}
END

View File

@@ -0,0 +1,90 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
EXTERN _tx_thread_current_ptr
EXTERN _txm_module_manager_kernel_dispatch
RSEG .text:CODE:NOROOT(5)
ARM
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _txm_module_manager_user_mode_entry Cortex-R4/MPU/IAR */
;/* 6.1 */
;/* AUTHOR */
;/* */
;/* Scott Larson, Microsoft Corporation */
;/* */
;/* DESCRIPTION */
;/* */
;/* This function allows modules to enter kernel mode. */
;/* */
;/* INPUT */
;/* */
;/* None */
;/* */
;/* OUTPUT */
;/* */
;/* None */
;/* */
;/* CALLS */
;/* */
;/* SVC 1 Enter kernel mode */
;/* SVC 2 Exit kernel mode */
;/* */
;/* CALLED BY */
;/* */
;/* Modules in user mode */
;/* */
;/* RELEASE HISTORY */
;/* */
;/* DATE NAME DESCRIPTION */
;/* */
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
;/* */
;/**************************************************************************/
PUBLIC _txm_module_manager_user_mode_entry
_txm_module_manager_user_mode_entry:
EXPORT _txm_system_mode_enter
_txm_system_mode_enter
SVC 1 ; Get out of user mode
_txm_module_priv
; At this point, we are in system mode.
; Save LR (and r3 for 8 byte aligned stack) and call the kernel dispatch function.
PUSH {r3, lr}
BL _txm_module_manager_kernel_dispatch
POP {r3, lr}
EXPORT _txm_system_mode_exit
_txm_system_mode_exit
; Trap to restore user mode while inside of ThreadX
SVC 2
BX lr ; Return to the caller
NOP
NOP
_txm_module_manager_user_mode_end
END