updated to 6.0.1 and added additional processors/toolchains
This commit is contained in:
134
ports/cortex_r4/ac6/example_build/sample_threadx/.cproject
Normal file
134
ports/cortex_r4/ac6/example_build/sample_threadx/.cproject
Normal 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=""${workspace_loc:/tx/inc_common}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/tx/inc_port}""/>
|
||||
</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=""${workspace_loc:/tx/Debug/tx.a}""/>
|
||||
</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>
|
||||
26
ports/cortex_r4/ac6/example_build/sample_threadx/.project
Normal file
26
ports/cortex_r4/ac6/example_build/sample_threadx/.project
Normal 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>
|
||||
@@ -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 "${INPUTS}"" 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 "${INPUTS}"" 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
239
ports/cortex_r4/ac6/example_build/sample_threadx/gic.c
Normal file
239
ports/cortex_r4/ac6/example_build/sample_threadx/gic.c
Normal 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 **/
|
||||
360
ports/cortex_r4/ac6/example_build/sample_threadx/gic.h
Normal file
360
ports/cortex_r4/ac6/example_build/sample_threadx/gic.h
Normal 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_ */
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
249
ports/cortex_r4/ac6/example_build/sample_threadx/startup.S
Normal file
249
ports/cortex_r4/ac6/example_build/sample_threadx/startup.S
Normal 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
|
||||
28
ports/cortex_r4/ac6/example_build/sample_threadx/timer.c
Normal file
28
ports/cortex_r4/ac6/example_build/sample_threadx/timer.c
Normal 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 */
|
||||
}
|
||||
4
ports/cortex_r4/ac6/example_build/sample_threadx/timer.h
Normal file
4
ports/cortex_r4/ac6/example_build/sample_threadx/timer.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
void timer_init();
|
||||
#endif
|
||||
135
ports/cortex_r4/ac6/example_build/tx/.cproject
Normal file
135
ports/cortex_r4/ac6/example_build/tx/.cproject
Normal 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=""${workspace_loc:/${ProjName}/inc_common}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc_port}""/>
|
||||
</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>
|
||||
48
ports/cortex_r4/ac6/example_build/tx/.project
Normal file
48
ports/cortex_r4/ac6/example_build/tx/.project
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>tx</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>inc_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>
|
||||
@@ -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 "${INPUTS}"" 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 "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
</extension>
|
||||
</configuration>
|
||||
</project>
|
||||
341
ports/cortex_r4/ac6/inc/tx_port.h
Normal file
341
ports/cortex_r4/ac6/inc/tx_port.h
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
392
ports/cortex_r4/ac6/readme_threadx.txt
Normal file
392
ports/cortex_r4/ac6/readme_threadx.txt
Normal 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
|
||||
|
||||
326
ports/cortex_r4/ac6/src/tx_initialize_low_level.S
Normal file
326
ports/cortex_r4/ac6/src/tx_initialize_low_level.S
Normal 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
|
||||
252
ports/cortex_r4/ac6/src/tx_thread_context_restore.S
Normal file
252
ports/cortex_r4/ac6/src/tx_thread_context_restore.S
Normal 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
|
||||
/* } */
|
||||
202
ports/cortex_r4/ac6/src/tx_thread_context_save.S
Normal file
202
ports/cortex_r4/ac6/src/tx_thread_context_save.S
Normal file
@@ -0,0 +1,202 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/* #include "tx_api.h" */
|
||||
/* #include "tx_thread.h" */
|
||||
|
||||
|
||||
.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
|
||||
|
||||
/* } */
|
||||
/* } */
|
||||
260
ports/cortex_r4/ac6/src/tx_thread_fiq_context_restore.S
Normal file
260
ports/cortex_r4/ac6/src/tx_thread_fiq_context_restore.S
Normal 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
|
||||
|
||||
/* } */
|
||||
209
ports/cortex_r4/ac6/src/tx_thread_fiq_context_save.S
Normal file
209
ports/cortex_r4/ac6/src/tx_thread_fiq_context_save.S
Normal 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
|
||||
108
ports/cortex_r4/ac6/src/tx_thread_fiq_nesting_end.S
Normal file
108
ports/cortex_r4/ac6/src/tx_thread_fiq_nesting_end.S
Normal file
@@ -0,0 +1,108 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/* #include "tx_api.h" */
|
||||
/* #include "tx_thread.h" */
|
||||
|
||||
#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
|
||||
/* } */
|
||||
|
||||
|
||||
|
||||
96
ports/cortex_r4/ac6/src/tx_thread_fiq_nesting_start.S
Normal file
96
ports/cortex_r4/ac6/src/tx_thread_fiq_nesting_start.S
Normal 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
|
||||
/* } */
|
||||
102
ports/cortex_r4/ac6/src/tx_thread_interrupt_control.S
Normal file
102
ports/cortex_r4/ac6/src/tx_thread_interrupt_control.S
Normal 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
|
||||
|
||||
/* } */
|
||||
96
ports/cortex_r4/ac6/src/tx_thread_interrupt_disable.S
Normal file
96
ports/cortex_r4/ac6/src/tx_thread_interrupt_disable.S
Normal 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
|
||||
|
||||
/* } */
|
||||
90
ports/cortex_r4/ac6/src/tx_thread_interrupt_restore.S
Normal file
90
ports/cortex_r4/ac6/src/tx_thread_interrupt_restore.S
Normal 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
|
||||
/* } */
|
||||
|
||||
|
||||
|
||||
105
ports/cortex_r4/ac6/src/tx_thread_irq_nesting_end.S
Normal file
105
ports/cortex_r4/ac6/src/tx_thread_irq_nesting_end.S
Normal 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
|
||||
/* } */
|
||||
96
ports/cortex_r4/ac6/src/tx_thread_irq_nesting_start.S
Normal file
96
ports/cortex_r4/ac6/src/tx_thread_irq_nesting_start.S
Normal 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
|
||||
/* } */
|
||||
230
ports/cortex_r4/ac6/src/tx_thread_schedule.S
Normal file
230
ports/cortex_r4/ac6/src/tx_thread_schedule.S
Normal 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
|
||||
164
ports/cortex_r4/ac6/src/tx_thread_stack_build.S
Normal file
164
ports/cortex_r4/ac6/src/tx_thread_stack_build.S
Normal 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
|
||||
/* } */
|
||||
162
ports/cortex_r4/ac6/src/tx_thread_system_return.S
Normal file
162
ports/cortex_r4/ac6/src/tx_thread_system_return.S
Normal 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!
|
||||
|
||||
/* } */
|
||||
193
ports/cortex_r4/ac6/src/tx_thread_vectored_context_save.S
Normal file
193
ports/cortex_r4/ac6/src/tx_thread_vectored_context_save.S
Normal 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
|
||||
|
||||
/* } */
|
||||
/* } */
|
||||
257
ports/cortex_r4/ac6/src/tx_timer_interrupt.S
Normal file
257
ports/cortex_r4/ac6/src/tx_timer_interrupt.S
Normal 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
|
||||
|
||||
/* } */
|
||||
Reference in New Issue
Block a user