updated to 6.0.1 and added additional processors/toolchains

This commit is contained in:
tameraw
2020-07-16 14:32:40 -07:00
parent f8e91d4762
commit 2c35570dc9
1285 changed files with 550383 additions and 50 deletions

View File

@@ -0,0 +1,134 @@
<?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_common}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/tx/inc_port}&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"/>
<option id="com.arm.tool.c.compiler.v6.base.options.target.enableToolSpecificSettings.255765850" 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.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"/>
<option id="com.arm.tool.assembler.v6.base.options.target.enableToolSpecificSettings.1647999833" name="Enable tool specific settings" superClass="com.arm.tool.assembler.v6.base.options.target.enableToolSpecificSettings" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<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>
</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</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="-1421062162261968450" 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="-1368649769080993602" 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>

File diff suppressed because one or more lines are too long

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,373 @@
/* 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"
#include "timer.h"
#define DEMO_STACK_SIZE 1024
#define DEMO_BYTE_POOL_SIZE 9120
#define DEMO_BLOCK_POOL_SIZE 100
#define DEMO_QUEUE_SIZE 100
/* Define the ThreadX object control blocks... */
TX_THREAD thread_0;
TX_THREAD thread_1;
TX_THREAD thread_2;
TX_THREAD thread_3;
TX_THREAD thread_4;
TX_THREAD thread_5;
TX_THREAD thread_6;
TX_THREAD thread_7;
TX_QUEUE queue_0;
TX_SEMAPHORE semaphore_0;
TX_MUTEX mutex_0;
TX_EVENT_FLAGS_GROUP event_flags_0;
TX_BYTE_POOL byte_pool_0;
TX_BLOCK_POOL block_pool_0;
/* Define the counters used in the demo application... */
ULONG thread_0_counter;
ULONG thread_1_counter;
ULONG thread_1_messages_sent;
ULONG thread_2_counter;
ULONG thread_2_messages_received;
ULONG thread_3_counter;
ULONG thread_4_counter;
ULONG thread_5_counter;
ULONG thread_6_counter;
ULONG thread_7_counter;
/* Define thread prototypes. */
void thread_0_entry(ULONG thread_input);
void thread_1_entry(ULONG thread_input);
void thread_2_entry(ULONG thread_input);
void thread_3_and_4_entry(ULONG thread_input);
void thread_5_entry(ULONG thread_input);
void thread_6_and_7_entry(ULONG thread_input);
/* Define main entry point. */
int main()
{
/* 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)
{
UINT status;
CHAR *pointer = TX_NULL;
/* Create a byte memory pool from which to allocate the thread stacks. */
tx_byte_pool_create(&byte_pool_0, "byte pool 0", first_unused_memory, DEMO_BYTE_POOL_SIZE);
/* Put system definition stuff in here, e.g. thread creates and other assorted
create information. */
/* Allocate the stack for thread 0. */
status = 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. */
status = 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;
}
}

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,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_swi_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_swi_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,135 @@
<?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.769643912" 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.2063467931" 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_common}&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.452232051" name="Enable tool specific settings" superClass="com.arm.tool.assembler.v6.base.options.target.enableToolSpecificSettings" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<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="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,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>tx</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>inc_common</name>
<type>2</type>
<locationURI>$%7BPARENT-5-PROJECT_LOC%7D/common/inc</locationURI>
</link>
<link>
<name>inc_port</name>
<type>2</type>
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/inc</locationURI>
</link>
<link>
<name>src_common</name>
<type>2</type>
<locationURI>$%7BPARENT-5-PROJECT_LOC%7D/common/src</locationURI>
</link>
<link>
<name>src_port</name>
<type>2</type>
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/src</locationURI>
</link>
</linkedResources>
</projectDescription>

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="-1386770049401848482" 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="-1368649769080993602" 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,341 @@
/**************************************************************************/
/* */
/* 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.0.1 */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file contains data type definitions that make the ThreadX */
/* real-time kernel function identically on a variety of different */
/* processor architectures. For example, the size or number of bits */
/* in an "int" data type vary between microprocessor architectures and */
/* even C compilers for the same microprocessor. ThreadX does not */
/* directly use native C data types. Instead, ThreadX creates its */
/* own special types that can be mapped to actual data types by this */
/* file to guarantee consistency in the interface and functionality. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
#ifndef TX_PORT_H
#define TX_PORT_H
/* Determine if the optional ThreadX user define file should be used. */
#ifdef TX_INCLUDE_USER_DEFINE_FILE
/* Yes, include the user defines in tx_user.h. The defines in this file may
alternately be defined on the command line. */
#include "tx_user.h"
#endif
/* Define compiler 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;
#define TX_THREAD_EXTENSION_3
/* Define the port extensions of the remaining ThreadX objects. */
#define TX_BLOCK_POOL_EXTENSION
#define TX_BYTE_POOL_EXTENSION
#define TX_EVENT_FLAGS_GROUP_EXTENSION
#define TX_MUTEX_EXTENSION
#define TX_QUEUE_EXTENSION
#define TX_SEMAPHORE_EXTENSION
#define TX_TIMER_EXTENSION
/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
#define TX_THREAD_USER_EXTENSION
#endif
/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
tx_thread_shell_entry, and tx_thread_terminate. */
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
/* Define the ThreadX object creation extensions for the remaining objects. */
#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
/* Define the ThreadX object deletion extensions for the remaining objects. */
#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
/* Determine if the ARM architecture has the CLZ instruction. This is available on
architectures v5 and above. If available, redefine the macro for calculating the
lowest bit set. */
#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 unsigned int 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 unsigned int 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.0 *";
#else
extern CHAR _tx_version_id[];
#endif
#endif

View File

@@ -0,0 +1,392 @@
Microsoft's Azure RTOS ThreadX for Cortex-R4
Thumb & 32-bit Mode
Using ARM Compiler 6 & DS
1. Import the ThreadX Projects
In order to build the ThreadX library and the ThreadX demonstration, first move
the project folders into your DS workspace directory. The project folders are
named 'tx' and 'sample_threadx' and are located in the installation directory.
Now that the projects are in the workspace directory, import them into DS by
doing the following for each project:
1. Click 'File -> Import -> Existing Projects into Workspace'
2. Set the root directory the project i.e. the 'tx' or 'sample_threadx' directory
3. Click 'Finish'
Note: the projects were made using DS-5, so DS will prompt you to migrate the projects.
This is expected, so please do so.
2. Building the ThreadX run-time Library
Building the ThreadX library is easy; simply right-click the Eclipse project
"tx" and then select the "Build Project" button. You should now observe the compilation
and assembly of the ThreadX library. This project build produces the ThreadX
library file tx.a.
3. Demonstration System
The ThreadX demonstration is designed to execute under the DS-5 debugger on the
VE_Cortex-R4 Bare Metal simulator.
Building the demonstration is easy; simply right-click the Eclipse project
"sample_threadx" and then select the "Build Project" button. You should now observe
the compilation and assembly of the ThreadX demonstration. This project build produces
the ThreadX library file sample_threadx.axf. Next, expand the demo ThreadX project folder
in the Project Explorer window, right-click on the 'cortex-r4_tx.launch' file, click
'Debug As', and then click 'cortex-r4_tx' from the submenu. This will cause the
debugger to load the sample_threadx.axf ELF file and run to main. You are now ready
to execute the ThreadX demonstration.
4. System Initialization
The entry point in ThreadX for the Cortex-R4 using ARM tools is at label
"Vectors". This is defined within startup.S in the sample_threadx project. In addition,
this is where all static and global pre-set C variable initialization processing
takes place.
The ThreadX tx_initialize_low_level.s file is responsible for determining the
first available RAM address for use by the application, which is supplied as the
sole input parameter to your application definition function, tx_application_define.
5. Register Usage and Stack Frames
The ARM compiler assumes that registers r0-r3 (a1-a4) and r12 (ip) are scratch
registers for each function. All other registers used by a C function must
be preserved by the function. ThreadX takes advantage of this in situations
where a context switch happens as a result of making a ThreadX service call
(which is itself a C function). In such cases, the saved context of a thread
is only the non-scratch registers.
The following defines the saved context stack frames for context switches
that occur as a result of interrupt handling or from thread-level API calls.
All suspended threads have one of these two types of stack frames. The top
of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the
associated thread control block TX_THREAD.
Offset Interrupted Stack Frame Non-Interrupt Stack Frame
0x00 1 0
0x04 CPSR CPSR
0x08 r0 (a1) r4 (v1)
0x0C r1 (a2) r5 (v2)
0x10 r2 (a3) r6 (v3)
0x14 r3 (a4) r7 (v4)
0x18 r4 (v1) r8 (v5)
0x1C r5 (v2) r9 (v6)
0x20 r6 (v3) r10 (v7)
0x24 r7 (v4) r11 (fp)
0x28 r8 (v5) r14 (lr)
0x2C r9 (v6)
0x30 r10 (v7)
0x34 r11 (fp)
0x38 r12 (ip)
0x3C r14 (lr)
0x40 PC
6. Improving Performance
The distribution version of ThreadX is built without any compiler
optimizations. This makes it easy to debug because you can trace or set
breakpoints inside of ThreadX itself. Of course, this costs some
performance. To make it run faster, you can change the build_threadx.bat file to
remove the -g option and enable all compiler optimizations.
In addition, you can eliminate the ThreadX basic API error checking by
compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING
defined.
7. Interrupt Handling
ThreadX provides complete and high-performance interrupt handling for Cortex-R4
targets. There are a certain set of requirements that are defined in the
following sub-sections:
7.1 Vector Area
The Cortex-R4 vectors start at address zero. The demonstration system startup.S
file contains the vectors and is loaded at address zero. On actual hardware platforms,
this area might have to be copied to address 0.
7.2 IRQ ISRs
ThreadX fully manages standard and vectored IRQ interrupts. ThreadX also supports nested
IRQ interrupts. The following sub-sections define the IRQ capabilities.
7.2.1 Standard IRQ ISRs
The standard ARM IRQ mechanism has a single interrupt vector at address 0x18. This IRQ
interrupt is managed by the __tx_irq_handler code in tx_initialize_low_level. The following
is the default IRQ handler defined in tx_initialize_low_level.s:
.global __tx_irq_handler
.type __tx_irq_handler, %function
__tx_irq_handler:
/* Jump to context save to save system context. */
B _tx_thread_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. */
/* Application IRQ handlers can be called here! */
...
/* Jump to context restore to restore system context. */
B _tx_thread_context_restore
7.2.2 Vectored IRQ ISRs
The vectored ARM ISR mechanism has multiple interrupt vectors at addresses specified
by the particular implementation. The following is an example ISR handler defined in
tx_initialize_low_level.s:
.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. */
/* Application IRQ handlers can be called here! */
...
/* Jump to context restore to restore system context. */
B _tx_thread_context_restore
7.2.3 Nested IRQ Support
By default, nested IRQ interrupt support is not enabled. To enable nested
IRQ support, the entire library should be built with TX_ENABLE_IRQ_NESTING
defined. With this defined, two new IRQ interrupt management services are
available, namely _tx_thread_irq_nesting_start and _tx_thread_irq_nesting_end.
These function should be called between the IRQ context save and restore
calls.
Execution between the calls to _tx_thread_irq_nesting_start and
_tx_thread_irq_nesting_end is enabled for IRQ nesting. This is achieved
by switching from IRQ mode to SYS mode and enabling IRQ interrupts.
The SYS mode stack is used during the SYS mode operation, which was
setup in tx_initialize_low_level.s. When nested IRQ interrupts are no longer required,
calling the _tx_thread_irq_nesting_end service disables nesting by disabling
IRQ interrupts and switching back to IRQ mode in preparation for the IRQ
context restore service.
The following is an example of enabling IRQ nested interrupts in a standard
IRQ handler:
.global __tx_irq_handler
.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:
...
/* 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. */
BL _tx_thread_irq_nesting_start
/* 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. */
BL _tx_thread_irq_nesting_end
/* Jump to context restore to restore system context. */
B _tx_thread_context_restore
7.3 FIQ Interrupts
By default, Cortex-R4 FIQ interrupts are left alone by ThreadX. Of course, this
means that the application is fully responsible for enabling the FIQ interrupt
and saving/restoring any registers used in the FIQ ISR processing. To globally
enable FIQ interrupts, the application should enable FIQ interrupts at the
beginning of each thread or before any threads are created in tx_application_define.
In addition, the application must ensure that no ThreadX service calls are made
from default FIQ ISRs, which is located in tx_initialize_low_level.s.
7.3.1 Managed FIQ Interrupts
Full ThreadX management of FIQ interrupts is provided if the ThreadX sources
are built with the TX_ENABLE_FIQ_SUPPORT defined. If the library is built
this way, the FIQ interrupt handlers are very similar to the IRQ interrupt
handlers defined previously. The following is default FIQ handler
defined in tx_initialize_low_level.s:
.global __tx_fiq_handler
.type __tx_fiq_handler, %function
.global __tx_fiq_processing_return
.type __tx_fiq_processing_return, %function
__tx_fiq_handler:
/* Jump to fiq context save to save system context. */
B _tx_thread_fiq_context_save
__tx_fiq_processing_return:
/* At this point execution is still in the FIQ mode. The CPSR, point of
interrupt, and all C scratch registers are available for use. */
/* Application FIQ handlers can be called here! */
/* Jump to fiq context restore to restore system context. */
B _tx_thread_fiq_context_restore
7.3.1.1 Nested FIQ Support
By default, nested FIQ interrupt support is not enabled. To enable nested
FIQ support, the entire library should be built with TX_ENABLE_FIQ_NESTING
defined. With this defined, two new FIQ interrupt management services are
available, namely _tx_thread_fiq_nesting_start and _tx_thread_fiq_nesting_end.
These function should be called between the FIQ context save and restore
calls.
Execution between the calls to _tx_thread_fiq_nesting_start and
_tx_thread_fiq_nesting_end is enabled for FIQ nesting. This is achieved
by switching from FIQ mode to SYS mode and enabling FIQ interrupts.
The SYS mode stack is used during the SYS mode operation, which was
setup in tx_initialize_low_level.s. When nested FIQ interrupts are no longer required,
calling the _tx_thread_fiq_nesting_end service disables nesting by disabling
FIQ interrupts and switching back to FIQ mode in preparation for the FIQ
context restore service.
The following is an example of enabling FIQ nested interrupts in the
typical FIQ handler:
.global __tx_fiq_handler
.type __tx_fiq_handler, %function
.global __tx_fiq_processing_return
.type __tx_fiq_processing_return, %function
__tx_fiq_handler:
/* Jump to fiq context save to save system context. */
B _tx_thread_fiq_context_save
__tx_fiq_processing_return:
/* At this point execution is still in the FIQ mode. The CPSR, point of
interrupt, and all C scratch registers are available for use. */
/* Enable nested FIQ interrupts. NOTE: Since this service returns
with FIQ interrupts enabled, all FIQ interrupt sources must be
cleared prior to calling this service. */
BL _tx_thread_fiq_nesting_start
/* Application FIQ handlers can be called here! */
/* Disable nested FIQ interrupts. The mode is switched back to
FIQ mode and FIQ interrupts are disable upon return. */
BL _tx_thread_fiq_nesting_end
/* Jump to fiq context restore to restore system context. */
B _tx_thread_fiq_context_restore
8. ThreadX Timer Interrupt
ThreadX requires a periodic interrupt source to manage all time-slicing,
thread sleeps, timeouts, and application timers. Without such a timer
interrupt source, these services are not functional. However, all other
ThreadX services are operational without a periodic timer source.
To add the timer interrupt processing, simply make a call to
_tx_timer_interrupt in the IRQ processing. An example of this can be
found in the file tx_initialize_low_level.s in the Integrator sub-directories.
9. Thumb/Cortex-R4 Mixed Mode
By default, ThreadX is setup for running in Cortex-R4 32-bit mode. This is
also true for the demonstration system. It is possible to build any
ThreadX file and/or the application in Thumb mode. To build ThreadX
assembly files in Thumb mode, define TX_THUMB_MODE.
10. VFP Support
By default, VFP support is disabled for each thread. If saving the context of the VFP registers
is needed, the following API call must be made from the context of the application thread - before
the VFP usage:
void tx_thread_vfp_enable(void);
After this API is called in the application, VFP registers will be saved/restored for this thread if it
is preempted via an interrupt. All other suspension of the this thread will not require the VFP registers
to be saved/restored.
To disable VFP register context saving, simply call the following API:
void tx_thread_vfp_disable(void);
Note that if VFP registers are used in ISRs, the save/restore of VFP registers must be done by the ISR.
In addition, the startup code is responsible for enabling VFP usage.
11. Revision History
For generic code revision information, please refer to the readme_threadx_generic.txt
file, which is included in your distribution. The following details the revision
information associated with this specific port of ThreadX:
06/30/2020 Initial ThreadX 6.0.1 version for Cortex-R4 using ARM tools.
Copyright(c) 1996-2020 Microsoft Corporation
https://azure.com/rtos

View File

@@ -0,0 +1,326 @@
/**************************************************************************/
/* */
/* 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 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/AC6 */
/* 6.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for any low-level processor */
/* initialization, including setting up interrupt vectors, setting */
/* up a periodic timer interrupt source, saving the system stack */
/* pointer for use in ISR processing later, and finding the first */
/* available RAM memory address for tx_application_define. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_initialize_low_level(VOID)
{ */
.global _tx_initialize_low_level
.type _tx_initialize_low_level, "function"
_tx_initialize_low_level:
/* 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
.global __tx_swi_interrupt
.type __tx_swi_interrupt, "function"
__tx_swi_interrupt:
B __tx_swi_interrupt // Software interrupt handler
.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
/* 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

View File

@@ -0,0 +1,252 @@
/**************************************************************************/
/* */
/* 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 SVC_MODE 0x13 // SVC mode
.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/AC6 */
/* 6.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function restores the interrupt context if it is processing a */
/* nested interrupt. If not, it returns to the interrupt thread if no */
/* preemption is necessary. Otherwise, if preemption is necessary or */
/* if no thread was running, the function returns to the scheduler. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_schedule Thread scheduling routine */
/* */
/* CALLED BY */
/* */
/* ISRs Interrupt Service Routines */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_context_restore(VOID)
{ */
.global _tx_thread_context_restore
.type _tx_thread_context_restore, "function"
_tx_thread_context_restore:
/* Lockout interrupts. */
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if // Disable IRQ and FIQ interrupts
#else
CPSID i // Disable IRQ interrupts
#endif
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR exit function to indicate an ISR is complete. */
BL _tx_execution_isr_exit // Call the ISR exit function
#endif
/* Determine if interrupts are nested. */
/* if (--_tx_thread_system_state)
{ */
LDR r3, =_tx_thread_system_state // Pickup address of system state 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 #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 #IRQ_MODE // Switch back to IRQ 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, #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(); */
B _tx_thread_schedule // Return to scheduler
/* } */
__tx_thread_idle_system_restore:
/* Just return back to the scheduler! */
CPS #SVC_MODE // Switch to SVC mode
B _tx_thread_schedule // 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.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function saves the context of an executing thread in the */
/* beginning of interrupt processing. The function also ensures that */
/* the system stack is used upon return to the calling ISR. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_context_save(VOID)
{ */
.global _tx_thread_context_save
.type _tx_thread_context_save, "function"
_tx_thread_context_save:
/* Upon entry to this routine, it is assumed that IRQ interrupts are locked
out, we are in IRQ mode, and all registers are intact. */
/* Check for a nested interrupt condition. */
/* if (_tx_thread_system_state++)
{ */
STMDB sp!, {r0-r3} // Save some working registers
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if // Disable FIQ interrupts
#endif
LDR r3, =_tx_thread_system_state // Pickup address of system state 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.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function restores the fiq interrupt context when processing a */
/* nested interrupt. If not, it returns to the interrupt thread if no */
/* preemption is necessary. Otherwise, if preemption is necessary or */
/* if no thread was running, the function returns to the scheduler. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_schedule Thread scheduling routine */
/* */
/* CALLED BY */
/* */
/* FIQ ISR Interrupt Service Routines */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_fiq_context_restore(VOID) */
/* { */
.global _tx_thread_fiq_context_restore
.type _tx_thread_fiq_context_restore, "function"
_tx_thread_fiq_context_restore:
/* Lockout interrupts. */
CPSID if // Disable IRQ and FIQ interrupts
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR exit function to indicate an ISR is complete. */
BL _tx_execution_isr_exit // Call the ISR exit function
#endif
/* Determine if interrupts are nested. */
/* if (--_tx_thread_system_state) */
/* { */
LDR r3, =_tx_thread_system_state // Pickup address of system state 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.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function saves the context of an executing thread in the */
/* beginning of interrupt processing. The function also ensures that */
/* the system stack is used upon return to the calling ISR. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_fiq_context_save(VOID) */
/* { */
.global _tx_thread_fiq_context_save
.type _tx_thread_fiq_context_save, "function"
_tx_thread_fiq_context_save:
/* Upon entry to this routine, it is assumed that IRQ interrupts are locked
out, we are in IRQ mode, and all registers are intact. */
/* Check for a nested interrupt condition. */
/* if (_tx_thread_system_state++) */
/* { */
STMDB sp!, {r0-r3} // Save some working registers
LDR r3, =_tx_thread_system_state // Pickup address of system state 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.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is called by the application from FIQ mode after */
/* _tx_thread_fiq_nesting_start has been called and switches the FIQ */
/* processing from system mode back to FIQ mode prior to the ISR */
/* calling _tx_thread_fiq_context_restore. Note that this function */
/* assumes the system stack pointer is in the same position after */
/* nesting start function was called. */
/* */
/* This function assumes that the system mode stack pointer was setup */
/* during low-level initialization (tx_initialize_low_level.s). */
/* */
/* This function returns with FIQ interrupts disabled. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_fiq_nesting_end(VOID) */
/* { */
.global _tx_thread_fiq_nesting_end
.type _tx_thread_fiq_nesting_end, "function"
_tx_thread_fiq_nesting_end:
MOV r3, lr // Save ISR return address
#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.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is called by the application from FIQ mode after */
/* _tx_thread_fiq_context_save has been called and switches the FIQ */
/* processing to the system mode so nested FIQ interrupt processing */
/* is possible (system mode has its own "lr" register). Note that */
/* this function assumes that the system mode stack pointer was setup */
/* during low-level initialization (tx_initialize_low_level.s). */
/* */
/* This function returns with FIQ interrupts enabled. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_fiq_nesting_start(VOID) */
/* { */
.global _tx_thread_fiq_nesting_start
.type _tx_thread_fiq_nesting_start, "function"
_tx_thread_fiq_nesting_start:
MOV r3, lr // Save ISR return address
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.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for changing the interrupt lockout */
/* posture of the system. */
/* */
/* INPUT */
/* */
/* new_posture New interrupt lockout posture */
/* */
/* OUTPUT */
/* */
/* old_posture Old interrupt lockout posture */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* UINT _tx_thread_interrupt_control(UINT new_posture) */
/* { */
.global _tx_thread_interrupt_control
.type _tx_thread_interrupt_control, "function"
_tx_thread_interrupt_control:
/* Pickup current interrupt lockout posture. */
MRS r3, CPSR // Pickup current CPSR
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.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for disabling interrupts */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* old_posture Old interrupt lockout posture */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* UINT _tx_thread_interrupt_disable(void) */
/* { */
.global _tx_thread_interrupt_disable
.type _tx_thread_interrupt_disable, "function"
_tx_thread_interrupt_disable:
/* Pickup current interrupt lockout posture. */
MRS r0, CPSR // Pickup current CPSR
/* Mask interrupts. */
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if // Disable IRQ and FIQ
#else
CPSID i // Disable IRQ
#endif
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.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for restoring interrupts to the state */
/* returned by a previous _tx_thread_interrupt_disable call. */
/* */
/* INPUT */
/* */
/* old_posture Old interrupt lockout posture */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* UINT _tx_thread_interrupt_restore(UINT old_posture) */
/* { */
.global _tx_thread_interrupt_restore
.type _tx_thread_interrupt_restore, "function"
_tx_thread_interrupt_restore:
/* Apply the new interrupt posture. */
MSR CPSR_c, r0 // Setup new CPSR
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.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is called by the application from IRQ mode after */
/* _tx_thread_irq_nesting_start has been called and switches the IRQ */
/* processing from system mode back to IRQ mode prior to the ISR */
/* calling _tx_thread_context_restore. Note that this function */
/* assumes the system stack pointer is in the same position after */
/* nesting start function was called. */
/* */
/* This function assumes that the system mode stack pointer was setup */
/* during low-level initialization (tx_initialize_low_level.s). */
/* */
/* This function returns with IRQ interrupts disabled. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_irq_nesting_end(VOID) */
/* { */
.global _tx_thread_irq_nesting_end
.type _tx_thread_irq_nesting_end, "function"
_tx_thread_irq_nesting_end:
MOV r3, lr // Save ISR return address
#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.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is called by the application from IRQ mode after */
/* _tx_thread_context_save has been called and switches the IRQ */
/* processing to the system mode so nested IRQ interrupt processing */
/* is possible (system mode has its own "lr" register). Note that */
/* this function assumes that the system mode stack pointer was setup */
/* during low-level initialization (tx_initialize_low_level.s). */
/* */
/* This function returns with IRQ interrupts enabled. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_irq_nesting_start(VOID) */
/* { */
.global _tx_thread_irq_nesting_start
.type _tx_thread_irq_nesting_start, "function"
_tx_thread_irq_nesting_start:
MOV r3, lr // Save ISR return address
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,230 @@
/**************************************************************************/
/* */
/* 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
.arm
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-R4/AC6 */
/* 6.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function waits for a thread control block pointer to appear in */
/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
/* in the variable, the corresponding thread is resumed. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* _tx_thread_context_restore Restore thread's context */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_schedule(VOID) */
/* { */
.global _tx_thread_schedule
.type _tx_thread_schedule, "function"
_tx_thread_schedule:
/* Enable interrupts. */
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSIE if // Enable IRQ and FIQ interrupts
#else
CPSIE i // Enable IRQ interrupts
#endif
/* Wait for a thread to execute. */
/* do */
/* { */
LDR r1, =_tx_thread_execute_ptr // Address of thread execute ptr
__tx_thread_schedule_loop:
LDR r0, [r1, #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
LDR sp, [r0, #8] // Switch stack pointers
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
/* Switch to the thread's stack. */
/* sp = _tx_thread_execute_ptr -> tx_thread_stack_ptr; */
/* Determine if an interrupt frame or a synchronous task suspension frame
is present. */
LDMIA sp!, {r4, r5} // Pickup the stack type and saved CPSR
CMP r4, #0 // Check for synchronous context switch
BEQ _tx_solicited_return
MSR SPSR_cxsf, r5 // Setup SPSR for return
#ifdef __ARM_FP
LDR r1, [r0, #144] // Pickup the VFP enabled flag
CMP r1, #0 // Is the VFP enabled?
BEQ _tx_skip_interrupt_vfp_restore // No, skip VFP interrupt restore
VLDMIA sp!, {D0-D15} // Recover D0-D15
LDR r4, [sp], #4 // Pickup FPSCR
VMSR FPSCR, r4 // Restore FPSCR
_tx_skip_interrupt_vfp_restore:
#endif
LDMIA sp!, {r0-r12, lr, pc}^ // Return to point of thread interrupt
_tx_solicited_return:
#ifdef __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
MSR CPSR_cxsf, r5 // Recover CPSR
LDMIA sp!, {r4-r11, lr} // Return to thread synchronously
BX lr // Return to caller
/* } */
#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 SVC_MODE 0x13 // SVC mode
#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
#define THUMB_BIT 0x20 // Thumb-bit
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_build Cortex-R4/AC6 */
/* 6.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function builds a stack frame on the supplied thread's stack. */
/* The stack frame results in a fake interrupt return to the supplied */
/* function pointer. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to thread control blk */
/* function_ptr Pointer to return function */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_thread_create Create thread service */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) */
/* { */
.global _tx_thread_stack_build
.type _tx_thread_stack_build, "function"
_tx_thread_stack_build:
/* Build a fake interrupt frame. The form of the fake interrupt stack
on the Cortex-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, #SVC_MODE // Build CPSR, SVC 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.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is target processor specific. It is used to transfer */
/* control from a thread back to the ThreadX system. Only a */
/* minimal context is saved since the compiler assumes temp registers */
/* are going to get slicked by a function call anyway. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_schedule Thread scheduling loop */
/* */
/* CALLED BY */
/* */
/* ThreadX components */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_system_return(VOID) */
/* { */
.global _tx_thread_system_return
.type _tx_thread_system_return, "function"
_tx_thread_system_return:
/* Save minimal context on the stack. */
STMDB sp!, {r4-r11, lr} // Save minimal context
LDR 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.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function saves the context of an executing thread in the */
/* beginning of interrupt processing. The function also ensures that */
/* the system stack is used upon return to the calling ISR. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_vectored_context_save(VOID) */
/* { */
.global _tx_thread_vectored_context_save
.type _tx_thread_vectored_context_save, "function"
_tx_thread_vectored_context_save:
/* Upon entry to this routine, it is assumed that IRQ interrupts are locked
out, we are in IRQ mode, and all registers are intact. */
/* Check for a nested interrupt condition. */
/* if (_tx_thread_system_state++) */
/* { */
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if // Disable IRQ and FIQ interrupts
#endif
LDR r3, =_tx_thread_system_state // Pickup address of system state 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.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the hardware timer interrupt. This */
/* processing includes incrementing the system clock and checking for */
/* time slice and/or timer expiration. If either is found, the */
/* interrupt context save/restore functions are called along with the */
/* expiration functions. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_timer_expiration_process Timer expiration processing */
/* _tx_thread_time_slice Time slice interrupted thread */
/* */
/* CALLED BY */
/* */
/* interrupt vector */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_timer_interrupt(VOID) */
/* { */
.global _tx_timer_interrupt
.type _tx_timer_interrupt, "function"
_tx_timer_interrupt:
/* Upon entry to this routine, it is assumed that context save has already
been called, and therefore the compiler scratch registers are available
for use. */
/* Increment the system clock. */
/* _tx_timer_system_clock++; */
LDR r1, =_tx_timer_system_clock // Pickup address of system clock
LDR r0, [r1, #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
/* } */