Preparing for the next release...
New port and demo project: Intel Galileo.pull/4/head
parent
8b5c27b679
commit
cff5cfdd4f
@ -0,0 +1,103 @@
|
|||||||
|
<?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="cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473">
|
||||||
|
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||||
|
<externalSettings/>
|
||||||
|
<extensions>
|
||||||
|
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||||
|
</extensions>
|
||||||
|
</storageModule>
|
||||||
|
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||||
|
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" errorParsers="org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GLDErrorParser" id="cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473" name="Debug" parent="cdt.managedbuild.config.gnu.cygwin.exe.debug" postannouncebuildStep="" postbuildStep="" preannouncebuildStep="" prebuildStep="">
|
||||||
|
<folderInfo id="cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473." name="/" resourcePath="">
|
||||||
|
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.base.143724896" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.base">
|
||||||
|
<option id="cdt.managedbuild.option.gnu.cross.prefix.1160671315" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix" value="i686-elf-" valueType="string"/>
|
||||||
|
<option id="cdt.managedbuild.option.gnu.cross.path.942625968" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" value="" valueType="string"/>
|
||||||
|
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.315548413" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
|
||||||
|
<builder buildPath="${workspace_loc:/RTOSDemo}/Debug" id="org.eclipse.cdt.build.core.internal.builder.1446204811" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" stopOnErr="true" superClass="org.eclipse.cdt.build.core.internal.builder"/>
|
||||||
|
<tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.850200804" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
|
||||||
|
<option id="gnu.c.compiler.option.include.paths.369547224" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Full_Demo}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Full_Demo}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Support_Files}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/include}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Full_Demo/Standard_Demo_Tasks/include}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/portable/IA32_flat}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}}""/>
|
||||||
|
</option>
|
||||||
|
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.option.optimization.level.1628552532" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.c.optimization.level.none" valueType="enumerated"/>
|
||||||
|
<option id="gnu.c.compiler.option.debugging.level.1363374967" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
||||||
|
<option id="gnu.c.compiler.option.dialect.std.1079108915" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
|
||||||
|
<option id="gnu.c.compiler.option.warnings.extrawarn.1052953868" name="Extra warnings (-Wextra)" superClass="gnu.c.compiler.option.warnings.extrawarn" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||||
|
<option id="gnu.c.compiler.option.misc.other.148628155" name="Other flags" superClass="gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-c -fmessage-length=0 -march=pentium -Wno-ignored-qualifiers -mno-ms-bitfields -ffunction-sections -ffreestanding" valueType="string"/>
|
||||||
|
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.308880891" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||||
|
</tool>
|
||||||
|
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.1667900842" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
|
||||||
|
<option id="gnu.cpp.compiler.option.optimization.level.556426180" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||||
|
<option id="gnu.cpp.compiler.option.debugging.level.105591713" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
|
||||||
|
</tool>
|
||||||
|
<tool command="gcc" id="cdt.managedbuild.tool.gnu.cross.c.linker.2047125905" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker">
|
||||||
|
<option id="gnu.c.link.option.nostdlibs.1858169787" name="No startup or default libs (-nostdlib)" superClass="gnu.c.link.option.nostdlibs" value="true" valueType="boolean"/>
|
||||||
|
<option id="gnu.c.link.option.nostart.16274397" name="Do not use standard start files (-nostartfiles)" superClass="gnu.c.link.option.nostart" value="false" valueType="boolean"/>
|
||||||
|
<option id="gnu.c.link.option.noshared.1817981723" name="No shared libraries (-static)" superClass="gnu.c.link.option.noshared" value="false" valueType="boolean"/>
|
||||||
|
<option id="gnu.c.link.option.nodeflibs.1892279432" name="Do not use default libraries (-nodefaultlibs)" superClass="gnu.c.link.option.nodeflibs" value="false" valueType="boolean"/>
|
||||||
|
<option id="gnu.c.link.option.ldflags.1391446951" name="Linker flags" superClass="gnu.c.link.option.ldflags" value="-Xlinker -T -Xlinker ..${PROJECT_LOC}/elf_ia32_efi.lds -Xlinker -Map=RTOSDemo.map -Xlinker --gc-sections" valueType="string"/>
|
||||||
|
<option id="gnu.c.link.option.libs.517070894" name="Libraries (-l)" superClass="gnu.c.link.option.libs" valueType="libs">
|
||||||
|
<listOptionValue builtIn="false" value="gcc"/>
|
||||||
|
</option>
|
||||||
|
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.480873713" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||||
|
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||||
|
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||||
|
</inputType>
|
||||||
|
</tool>
|
||||||
|
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.1304180380" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker"/>
|
||||||
|
<tool id="cdt.managedbuild.tool.gnu.cross.archiver.2001524857" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
|
||||||
|
<tool command="gcc" id="cdt.managedbuild.tool.gnu.cross.assembler.500911803" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
|
||||||
|
<option id="gnu.both.asm.option.include.paths.1341458440" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/portable/IA32_flat}""/>
|
||||||
|
</option>
|
||||||
|
<option id="gnu.both.asm.option.flags.342663249" name="Assembler flags" superClass="gnu.both.asm.option.flags" value="-Wa,--gdwarf2 -Wa,-march=pentium -c" valueType="string"/>
|
||||||
|
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.458498164" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||||
|
</tool>
|
||||||
|
</toolChain>
|
||||||
|
</folderInfo>
|
||||||
|
<sourceEntries>
|
||||||
|
<entry excluding="Support_Files/stdlib_functions.c|nops.c|Source|uart.c|early_uart.c" 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="RTOSDemo.cdt.managedbuild.target.gnu.cygwin.exe.531908557" name="Executable" projectType="cdt.managedbuild.target.gnu.cygwin.exe"/>
|
||||||
|
</storageModule>
|
||||||
|
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||||
|
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||||
|
<configuration configurationName="Debug">
|
||||||
|
<resource resourceType="PROJECT" workspacePath="/RTOSDemo"/>
|
||||||
|
</configuration>
|
||||||
|
</storageModule>
|
||||||
|
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||||
|
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||||
|
<storageModule moduleId="scannerConfiguration">
|
||||||
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||||
|
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473;cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473.;cdt.managedbuild.tool.gnu.c.compiler.cygwin.exe.debug.1450966283;cdt.managedbuild.tool.gnu.c.compiler.input.cygwin.88373151">
|
||||||
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||||
|
</scannerConfigBuildInfo>
|
||||||
|
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473;cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473.;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.1366728385;cdt.managedbuild.tool.gnu.c.compiler.input.58867770">
|
||||||
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||||
|
</scannerConfigBuildInfo>
|
||||||
|
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473;cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473.;cdt.managedbuild.tool.gnu.cross.c.compiler.850200804;cdt.managedbuild.tool.gnu.c.compiler.input.308880891">
|
||||||
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||||
|
</scannerConfigBuildInfo>
|
||||||
|
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473;cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473.;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.1511730062;cdt.managedbuild.tool.gnu.c.compiler.input.1872488295">
|
||||||
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||||
|
</scannerConfigBuildInfo>
|
||||||
|
</storageModule>
|
||||||
|
</cproject>
|
@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>RTOSDemo</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>FreeRTOS_Source</name>
|
||||||
|
<type>2</type>
|
||||||
|
<locationURI>FREERTOS_ROOT/Source</locationURI>
|
||||||
|
</link>
|
||||||
|
<link>
|
||||||
|
<name>Full_Demo/Standard_Demo_Tasks</name>
|
||||||
|
<type>2</type>
|
||||||
|
<locationURI>FREERTOS_ROOT/Demo/Common</locationURI>
|
||||||
|
</link>
|
||||||
|
</linkedResources>
|
||||||
|
<filteredResources>
|
||||||
|
<filter>
|
||||||
|
<id>1397138529515</id>
|
||||||
|
<name>FreeRTOS_Source/portable</name>
|
||||||
|
<type>9</type>
|
||||||
|
<matcher>
|
||||||
|
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||||
|
<arguments>1.0-name-matches-false-false-IA32_flat</arguments>
|
||||||
|
</matcher>
|
||||||
|
</filter>
|
||||||
|
<filter>
|
||||||
|
<id>1397138529531</id>
|
||||||
|
<name>FreeRTOS_Source/portable</name>
|
||||||
|
<type>9</type>
|
||||||
|
<matcher>
|
||||||
|
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||||
|
<arguments>1.0-name-matches-false-false-MemMang</arguments>
|
||||||
|
</matcher>
|
||||||
|
</filter>
|
||||||
|
<filter>
|
||||||
|
<id>1397138545742</id>
|
||||||
|
<name>FreeRTOS_Source/portable/MemMang</name>
|
||||||
|
<type>5</type>
|
||||||
|
<matcher>
|
||||||
|
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||||
|
<arguments>1.0-name-matches-false-false-heap_4.c</arguments>
|
||||||
|
</matcher>
|
||||||
|
</filter>
|
||||||
|
</filteredResources>
|
||||||
|
<variableList>
|
||||||
|
<variable>
|
||||||
|
<name>FREERTOS_ROOT</name>
|
||||||
|
<value>$%7BPARENT-2-PROJECT_LOC%7D</value>
|
||||||
|
</variable>
|
||||||
|
</variableList>
|
||||||
|
</projectDescription>
|
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<project>
|
||||||
|
<configuration id="cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473" 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="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1445952490268027060" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC 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>
|
@ -0,0 +1,69 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.cdt.codan.checkers.errnoreturn=-Warning
|
||||||
|
org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
|
||||||
|
org.eclipse.cdt.codan.checkers.errreturnvalue=-Error
|
||||||
|
org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.checkers.noreturn=-Error
|
||||||
|
org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=-Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=-Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.CatchByReference=-Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=-Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.InvalidArguments=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=-Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.OverloadProblem=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=-Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=-Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=-Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=-Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=-Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=-Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=-Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||||
|
org.eclipse.cdt.qt.core.qtproblem=Warning
|
||||||
|
org.eclipse.cdt.qt.core.qtproblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_ON_FILE_OPEN\=>true,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
@ -0,0 +1,6 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
environment/project/cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473/MSYS_HOME/delimiter=;
|
||||||
|
environment/project/cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473/MSYS_HOME/operation=replace
|
||||||
|
environment/project/cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473/MSYS_HOME/value=
|
||||||
|
environment/project/cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473/append=true
|
||||||
|
environment/project/cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473/appendContributed=true
|
@ -0,0 +1,11 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473/CPATH/delimiter=;
|
||||||
|
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473/CPATH/operation=remove
|
||||||
|
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473/C_INCLUDE_PATH/delimiter=;
|
||||||
|
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473/C_INCLUDE_PATH/operation=remove
|
||||||
|
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473/append=true
|
||||||
|
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473/appendContributed=true
|
||||||
|
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473/LIBRARY_PATH/delimiter=;
|
||||||
|
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473/LIBRARY_PATH/operation=remove
|
||||||
|
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473/append=true
|
||||||
|
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.cygwin.exe.debug.5899473/appendContributed=true
|
@ -0,0 +1,2 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
|
@ -0,0 +1,247 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* NOTE 1: This project provides two demo applications. A simple blinky style
|
||||||
|
* project, and a more comprehensive test and demo application. The
|
||||||
|
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
|
||||||
|
* between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
|
||||||
|
* in main.c. This file implements the simply blinky style version.
|
||||||
|
*
|
||||||
|
* NOTE 2: This file only contains the source code that is specific to the
|
||||||
|
* basic demo. Generic functions, such FreeRTOS hook functions, and functions
|
||||||
|
* required to configure the hardware are defined in main.c.
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* See http://www.FreeRTOS.org/RTOS_Intel_Quark_Galileo_GCC.html for usage
|
||||||
|
* instructions.
|
||||||
|
*
|
||||||
|
* main_blinky() creates one queue, and two tasks. It then starts the
|
||||||
|
* scheduler.
|
||||||
|
*
|
||||||
|
* The Queue Send Task:
|
||||||
|
* The queue send task is implemented by the prvQueueSendTask() function in
|
||||||
|
* this file. prvQueueSendTask() sits in a loop that causes it to repeatedly
|
||||||
|
* block for 200 milliseconds, before sending the value 100 to the queue that
|
||||||
|
* was created within main_blinky(). Once the value is sent, the task loops
|
||||||
|
* back around to block for another 200 milliseconds...and so on.
|
||||||
|
*
|
||||||
|
* The Queue Receive Task:
|
||||||
|
* The queue receive task is implemented by the prvQueueReceiveTask() function
|
||||||
|
* in this file. prvQueueReceiveTask() sits in a loop where it repeatedly
|
||||||
|
* blocks on attempts to read data from the queue that was created within
|
||||||
|
* main_blinky(). When data is received, the task checks the value of the
|
||||||
|
* data, and if the value equals the expected 100, outputs a message to the COM
|
||||||
|
* port. The 'block time' parameter passed to the queue receive function
|
||||||
|
* specifies that the task should be held in the Blocked state indefinitely to
|
||||||
|
* wait for data to be available on the queue. The queue receive task will only
|
||||||
|
* leave the Blocked state when the queue send task writes to the queue. As the
|
||||||
|
* queue send task writes to the queue every 200 milliseconds, the queue receive
|
||||||
|
* task leaves the Blocked state every 200 milliseconds, and therefore writes to
|
||||||
|
* the COM port every 200 milliseconds.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Kernel includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* Added Galileo SERIAL support */
|
||||||
|
#include "galileo_support.h"
|
||||||
|
|
||||||
|
/* Priorities at which the tasks are created. */
|
||||||
|
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||||
|
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||||
|
|
||||||
|
/* The rate at which data is sent to the queue. The 200ms value is converted
|
||||||
|
to ticks using the portTICK_PERIOD_MS constant. */
|
||||||
|
#define mainQUEUE_SEND_FREQUENCY_MS ( pdMS_TO_TICKS( 200 ) )
|
||||||
|
|
||||||
|
/* The number of items the queue can hold. This is 1 as the receive task
|
||||||
|
will remove items as they are added, meaning the send task should always find
|
||||||
|
the queue empty. */
|
||||||
|
#define mainQUEUE_LENGTH ( 1 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The tasks as described in the comments at the top of this file.
|
||||||
|
*/
|
||||||
|
static void prvQueueReceiveTask( void *pvParameters );
|
||||||
|
static void prvQueueSendTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called by main() to create the simply blinky style application if
|
||||||
|
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
|
||||||
|
*/
|
||||||
|
void main_blinky( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The queue used by both tasks. */
|
||||||
|
static QueueHandle_t xQueue = NULL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* See http://www.FreeRTOS.org/RTOS_Intel_Quark_Galileo_GCC.html for usage
|
||||||
|
instructions. */
|
||||||
|
void main_blinky( void )
|
||||||
|
{
|
||||||
|
/* Create the queue. */
|
||||||
|
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );
|
||||||
|
|
||||||
|
if( xQueue != NULL )
|
||||||
|
{
|
||||||
|
/* Start the two tasks as described in the comments at the top of this
|
||||||
|
file. */
|
||||||
|
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
|
||||||
|
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
|
||||||
|
configMINIMAL_STACK_SIZE * 2, /* The size of the stack to allocate to the task. */
|
||||||
|
NULL, /* The parameter passed to the task - not used in this case. */
|
||||||
|
mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
|
||||||
|
NULL ); /* The task handle is not required, so NULL is passed. */
|
||||||
|
|
||||||
|
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE * 2, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
|
||||||
|
|
||||||
|
/* Start the tasks and timer running. */
|
||||||
|
vTaskStartScheduler();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If all is well, the scheduler will now be running, and the following
|
||||||
|
line will never be reached. If the following line does execute, then
|
||||||
|
there was either insufficient FreeRTOS heap memory available for the idle
|
||||||
|
and/or timer tasks to be created, or vTaskStartScheduler() was called from
|
||||||
|
User mode. See the memory management section on the FreeRTOS web site for
|
||||||
|
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
|
||||||
|
mode from which main() is called is set in the C start up code and must be
|
||||||
|
a privileged mode (not user mode). */
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvQueueSendTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
TickType_t xNextWakeTime;
|
||||||
|
const uint32_t ulValueToSend = 100UL;
|
||||||
|
|
||||||
|
/* Remove compiler warning about unused parameter. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Initialise xNextWakeTime - this only needs to be done once. */
|
||||||
|
xNextWakeTime = xTaskGetTickCount();
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Place this task in the blocked state until it is time to run again. */
|
||||||
|
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
|
||||||
|
|
||||||
|
/* Send to the queue - causing the queue receive task to unblock and
|
||||||
|
write to the COM port. 0 is used as the block time so the sending
|
||||||
|
operation will not block - it shouldn't need to block as the queue
|
||||||
|
should always be empty at this point in the code. */
|
||||||
|
xQueueSend( xQueue, &ulValueToSend, 0U );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvQueueReceiveTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
uint32_t ulReceivedValue, ulLEDStatus;
|
||||||
|
const uint32_t ulExpectedValue = 100UL;
|
||||||
|
|
||||||
|
/* Remove compiler warning about unused parameter. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Initial cursor position to skip a line) */
|
||||||
|
g_printf_rcc( 5, 2, DEFAULT_SCREEN_COLOR, "LED on the Galileo board should be blinking." );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Wait until something arrives in the queue - this task will block
|
||||||
|
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
|
||||||
|
FreeRTOSConfig.h. */
|
||||||
|
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
|
||||||
|
|
||||||
|
/* To get here something must have been received from the queue, but
|
||||||
|
is it the expected value? If it is, write a message to the COMP
|
||||||
|
port. */
|
||||||
|
if( ulReceivedValue == ulExpectedValue )
|
||||||
|
{
|
||||||
|
/* Toggle the LED, and also print the LED toggle state to the
|
||||||
|
UART. */
|
||||||
|
ulLEDStatus = ulBlinkLED();
|
||||||
|
|
||||||
|
/* Print the LED status */
|
||||||
|
g_printf_rcc( 6, 2, DEFAULT_SCREEN_COLOR, "LED State = %d\r\n", ( int ) ulLEDStatus );
|
||||||
|
ulReceivedValue = 0U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -0,0 +1,250 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERTOS_CONFIG_H
|
||||||
|
#define FREERTOS_CONFIG_H
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Application specific definitions.
|
||||||
|
*
|
||||||
|
* These definitions should be adjusted for your particular hardware and
|
||||||
|
* application requirements.
|
||||||
|
*
|
||||||
|
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||||
|
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||||
|
*
|
||||||
|
* See http://www.freertos.org/a00110.html.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The FreeRTOS Quark port implements a full interrupt nesting model.
|
||||||
|
*
|
||||||
|
* Interrupts that are assigned a priority at or below
|
||||||
|
* configMAX_API_CALL_INTERRUPT_PRIORITY can call interrupt safe API functions
|
||||||
|
* and will nest.
|
||||||
|
*
|
||||||
|
* Interrupts that are assigned a priority above
|
||||||
|
* configMAX_API_CALL_INTERRUPT_PRIORITY cannot call any FreeRTOS API functions,
|
||||||
|
* will nest, and will not be masked by FreeRTOS critical sections (although all
|
||||||
|
* interrupts are briefly masked by the hardware itself on interrupt entry).
|
||||||
|
*
|
||||||
|
* FreeRTOS functions that can be called from an interrupt are those that end in
|
||||||
|
* "FromISR". FreeRTOS maintains a separate interrupt safe API to enable
|
||||||
|
* interrupt entry to be shorter, faster, simpler and smaller.
|
||||||
|
*
|
||||||
|
* User definable interrupt priorities range from 2 (the lowest) to 15 (the
|
||||||
|
* highest).
|
||||||
|
*/
|
||||||
|
#define configMAX_API_CALL_INTERRUPT_PRIORITY 10
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupt entry code will switch the stack in use to a dedicated system
|
||||||
|
* stack.
|
||||||
|
*
|
||||||
|
* configISR_STACK_SIZE defines the number of 32-bit values that can be stored
|
||||||
|
* on the system stack, and must be large enough to hold a potentially nested
|
||||||
|
* interrupt stack frame.
|
||||||
|
*
|
||||||
|
* Changing this parameter necessitates a complete rebuild so the assembly files
|
||||||
|
* also get rebuilt.
|
||||||
|
*/
|
||||||
|
#define configISR_STACK_SIZE 350
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If configSUPPORT_FPU is set to 1 then tasks can optionally have a floating
|
||||||
|
* point context (the floating point registers will be saved as part of the task
|
||||||
|
* context). If configSUPPORT_FPU is set to 1 then a task must *not* use any
|
||||||
|
* floating point instructions until after it has called vPortTaskUsesFPU().
|
||||||
|
*
|
||||||
|
* If configSUPPORT_FPU is set to 0 then floating point instructions must never
|
||||||
|
* be used.
|
||||||
|
*/
|
||||||
|
#define configSUPPORT_FPU 1
|
||||||
|
|
||||||
|
/* There are two ways of implementing interrupt handlers:
|
||||||
|
*
|
||||||
|
* 1) As standard C functions -
|
||||||
|
*
|
||||||
|
* This method can only be used if configUSE_COMMON_INTERRUPT_ENTRY_POINT
|
||||||
|
* is set to 1. The C function is installed using
|
||||||
|
* xPortRegisterCInterruptHandler().
|
||||||
|
*
|
||||||
|
* This is the simplest of the two methods but incurs a slightly longer
|
||||||
|
* interrupt entry time.
|
||||||
|
*
|
||||||
|
* 2) By using an assembly stub that wraps the handler in the FreeRTOS
|
||||||
|
* portFREERTOS_INTERRUPT_ENTRY and portFREERTOS_INTERRUPT_EXIT macros. The handler is installed
|
||||||
|
* using xPortInstallInterruptHandler().
|
||||||
|
*
|
||||||
|
* This method can always be used. It is slightly more complex than
|
||||||
|
* method 1 but benefits from a faster interrupt entry time.
|
||||||
|
*
|
||||||
|
* Changing this parameter necessitates a complete clean build.
|
||||||
|
*/
|
||||||
|
#define configUSE_COMMON_INTERRUPT_ENTRY_POINT 1
|
||||||
|
|
||||||
|
#define configCPU_CLOCK_HZ ( 400000000UL )
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
#define configMINIMAL_STACK_SIZE ( 125 )
|
||||||
|
#define configUSE_TICKLESS_IDLE 0
|
||||||
|
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
|
||||||
|
#define configUSE_PREEMPTION 1
|
||||||
|
#define configUSE_IDLE_HOOK 1
|
||||||
|
#define configUSE_TICK_HOOK 1
|
||||||
|
#define configMAX_PRIORITIES ( 7 )
|
||||||
|
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 55 * 1024 ) )
|
||||||
|
#define configMAX_TASK_NAME_LEN ( 10 )
|
||||||
|
#define configUSE_TRACE_FACILITY 0
|
||||||
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
|
#define configUSE_MUTEXES 1
|
||||||
|
#define configQUEUE_REGISTRY_SIZE 8
|
||||||
|
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||||
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
|
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||||
|
#define configUSE_APPLICATION_TASK_TAG 0
|
||||||
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
|
#define configUSE_QUEUE_SETS 1
|
||||||
|
#define configUSE_TASK_NOTIFICATIONS 1
|
||||||
|
|
||||||
|
/* Co-routine definitions. */
|
||||||
|
#define configUSE_CO_ROUTINES 0
|
||||||
|
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||||
|
|
||||||
|
/* Software timer definitions. */
|
||||||
|
#define configUSE_TIMERS 1
|
||||||
|
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
|
||||||
|
#define configTIMER_QUEUE_LENGTH 8
|
||||||
|
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
|
||||||
|
|
||||||
|
/* Set the following definitions to 1 to include the API function, or zero
|
||||||
|
to exclude the API function. */
|
||||||
|
#define INCLUDE_vTaskPrioritySet 1
|
||||||
|
#define INCLUDE_uxTaskPriorityGet 1
|
||||||
|
#define INCLUDE_vTaskDelete 1
|
||||||
|
#define INCLUDE_vTaskCleanUpResources 1
|
||||||
|
#define INCLUDE_vTaskSuspend 1
|
||||||
|
#define INCLUDE_vTaskDelayUntil 1
|
||||||
|
#define INCLUDE_vTaskDelay 1
|
||||||
|
#define INCLUDE_xTimerPendFunctionCall 1
|
||||||
|
#define INCLUDE_eTaskGetState 1
|
||||||
|
|
||||||
|
/* This demo makes use of one or more example stats formatting functions. These
|
||||||
|
format the raw data provided by the uxTaskGetSystemState() function in to human
|
||||||
|
readable ASCII form. See the notes in the implementation of vTaskList() within
|
||||||
|
FreeRTOS/Source/tasks.c for limitations. */
|
||||||
|
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
|
||||||
|
|
||||||
|
/* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS is not required because the time base
|
||||||
|
comes from the ulHighFrequencyTimerCounts variable which is incremented in a
|
||||||
|
high frequency timer that is already being started as part of the interrupt
|
||||||
|
nesting test. */
|
||||||
|
#define configGENERATE_RUN_TIME_STATS 0
|
||||||
|
|
||||||
|
/* The size of the global output buffer that is available for use when there
|
||||||
|
are multiple command interpreters running at once (for example, one on a UART
|
||||||
|
and one on TCP/IP). This is done to prevent an output buffer being defined by
|
||||||
|
each implementation - which would waste RAM. In this case, there is only one
|
||||||
|
command interpreter running. */
|
||||||
|
#define configCOMMAND_INT_MAX_OUTPUT_SIZE 2096
|
||||||
|
|
||||||
|
/* This file is included from assembler files - make sure C code is not included
|
||||||
|
in assembler files. */
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
void vAssertCalled( const char * pcFile, unsigned long ulLine );
|
||||||
|
void vConfigureTickInterrupt( void );
|
||||||
|
void vClearTickInterrupt( void );
|
||||||
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Normal assert() semantics without relying on the provision of an assert.h
|
||||||
|
header file. */
|
||||||
|
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****** Hardware/compiler specific settings. *******************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The application must provide a function that configures a peripheral to
|
||||||
|
* create the FreeRTOS tick interrupt, then define configSETUP_TICK_INTERRUPT()
|
||||||
|
* in FreeRTOSConfig.h to call the function. This file contains a function
|
||||||
|
* that is suitable for use on the Zynq MPU. FreeRTOS_Tick_Handler() must
|
||||||
|
* be installed as the peripheral's interrupt handler.
|
||||||
|
*/
|
||||||
|
#define configSETUP_TICK_INTERRUPT() vConfigureTickInterrupt()
|
||||||
|
#define configCLEAR_TICK_INTERRUPT() vClearTickInterrupt()
|
||||||
|
|
||||||
|
|
||||||
|
/* Compiler specifics. */
|
||||||
|
#define fabs( x ) __builtin_fabs( ( x ) )
|
||||||
|
|
||||||
|
#endif /* FREERTOS_CONFIG_H */
|
||||||
|
|
@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Provides the port specific part of the standard IntQ test, which is
|
||||||
|
* implemented in FreeRTOS/Demo/Common/Minimal/IntQueue.c. Three HPET timers
|
||||||
|
* are used to generate the interrupts. The timers are configured in
|
||||||
|
* prvSetupHardware(), in main.c.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
|
||||||
|
/* Demo includes. */
|
||||||
|
#include "IntQueueTimer.h"
|
||||||
|
#include "IntQueue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prototypes of the callback functions which are called from the HPET timer
|
||||||
|
* support file. For demonstration purposes, timer 0 and timer 1 are standard
|
||||||
|
* C functions that use the central interrupt handler, and are installed using
|
||||||
|
* xPortRegisterCInterruptHandler() - and timer 2 uses its own interrupt entry
|
||||||
|
* asm wrapper code and is installed using xPortInstallInterruptHandler(). For
|
||||||
|
* convenience the asm wrapper which calls vApplicationHPETTimer1Handler(), is
|
||||||
|
* implemented in RegTest.S. See
|
||||||
|
* http://www.freertos.org/RTOS_Intel_Quark_Galileo_GCC.html#interrupts for more
|
||||||
|
* details.
|
||||||
|
*/
|
||||||
|
void vApplicationHPETTimer0Handler( void );
|
||||||
|
void vApplicationHPETTimer1Handler( void );
|
||||||
|
void vApplicationHPETTimer2Handler( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set to pdTRUE when vInitialiseTimerForIntQueueTest() is called so the timer
|
||||||
|
* callback functions know the scheduler is running and the tests can run.
|
||||||
|
*/
|
||||||
|
static volatile BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
||||||
|
/* Used to count the nesting depth to ensure the test is testing what it is
|
||||||
|
intended to test. */
|
||||||
|
static volatile uint32_t ulMaxInterruptNesting = 0;
|
||||||
|
extern volatile uint32_t ulInterruptNesting;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vInitialiseTimerForIntQueueTest( void )
|
||||||
|
{
|
||||||
|
/* The HPET timers are set up in main(), before the scheduler is started,
|
||||||
|
so there is nothing to do here other than note the scheduler is now running.
|
||||||
|
This could be done by calling a FreeRTOS API function, but its convenient
|
||||||
|
and efficient just to store the fact in a file scope variable. */
|
||||||
|
xSchedulerRunning = pdTRUE;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vApplicationHPETTimer0Handler( void )
|
||||||
|
{
|
||||||
|
BaseType_t xHigherPriorityTaskWoken;
|
||||||
|
|
||||||
|
if( xSchedulerRunning != pdFALSE )
|
||||||
|
{
|
||||||
|
if( ulInterruptNesting > ulMaxInterruptNesting )
|
||||||
|
{
|
||||||
|
ulMaxInterruptNesting = ulInterruptNesting;
|
||||||
|
}
|
||||||
|
|
||||||
|
xHigherPriorityTaskWoken = xFirstTimerHandler();
|
||||||
|
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vApplicationHPETTimer1Handler( void )
|
||||||
|
{
|
||||||
|
BaseType_t xHigherPriorityTaskWoken;
|
||||||
|
|
||||||
|
if( xSchedulerRunning != pdFALSE )
|
||||||
|
{
|
||||||
|
if( ulInterruptNesting > ulMaxInterruptNesting )
|
||||||
|
{
|
||||||
|
ulMaxInterruptNesting = ulInterruptNesting;
|
||||||
|
}
|
||||||
|
|
||||||
|
xHigherPriorityTaskWoken = xSecondTimerHandler();
|
||||||
|
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vApplicationHPETTimer2Handler( void )
|
||||||
|
{
|
||||||
|
if( ulInterruptNesting > ulMaxInterruptNesting )
|
||||||
|
{
|
||||||
|
ulMaxInterruptNesting = ulInterruptNesting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INT_QUEUE_TIMER_H
|
||||||
|
#define INT_QUEUE_TIMER_H
|
||||||
|
|
||||||
|
void vInitialiseTimerForIntQueueTest( void );
|
||||||
|
portBASE_TYPE xTimer0Handler( void );
|
||||||
|
portBASE_TYPE xTimer1Handler( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,325 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
.file "RegTest.S"
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
#include "ISR_Support.h"
|
||||||
|
|
||||||
|
.extern ulRegTest1Counter
|
||||||
|
.extern ulRegTest2Counter
|
||||||
|
.extern dRegTest1_st7
|
||||||
|
.extern dRegTest1_st6
|
||||||
|
.extern dRegTest1_st5
|
||||||
|
.extern dRegTest1_st4
|
||||||
|
.extern dRegTest1_st3
|
||||||
|
.extern dRegTest1_st2
|
||||||
|
.extern dRegTest1_st1
|
||||||
|
.extern dRegTest2_st7
|
||||||
|
.extern dRegTest2_st6
|
||||||
|
.extern dRegTest2_st5
|
||||||
|
.extern dRegTest2_st4
|
||||||
|
.extern dRegTest2_st3
|
||||||
|
.extern dRegTest2_st2
|
||||||
|
.extern dRegTest2_st1
|
||||||
|
.extern vGenerateYieldInterrupt
|
||||||
|
.extern vHPETIRQHandler1
|
||||||
|
|
||||||
|
.global vRegTest1
|
||||||
|
.global vRegTest2
|
||||||
|
.global vApplicationHPETTimer1Wrapper
|
||||||
|
|
||||||
|
.section .text.last /* Push up the memory to check executing from higher memory addresses. */
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
.func vRegTest1
|
||||||
|
vRegTest1:
|
||||||
|
|
||||||
|
/* Set initial values into the general purpose registers. */
|
||||||
|
movl $0x11111111, %eax
|
||||||
|
movl $0x22222222, %ebx
|
||||||
|
movl $0x33333333, %ecx
|
||||||
|
movl $0x44444444, %edx
|
||||||
|
movl $0x55555555, %esi
|
||||||
|
movl $0x66666666, %edi
|
||||||
|
|
||||||
|
/* Set initial values into the floating point registers. */
|
||||||
|
.if configSUPPORT_FPU == 1
|
||||||
|
fldl dRegTest1_st7
|
||||||
|
fldl dRegTest1_st6
|
||||||
|
fldl dRegTest1_st5
|
||||||
|
fldl dRegTest1_st4
|
||||||
|
fldl dRegTest1_st3
|
||||||
|
fldl dRegTest1_st2
|
||||||
|
fldl dRegTest1_st1
|
||||||
|
.endif /* configSUPPORT_FPU */
|
||||||
|
|
||||||
|
_RegTest1Loop:
|
||||||
|
|
||||||
|
/* Loop checking the values originally loaded into the general purpose
|
||||||
|
registers remain through the life of the task. */
|
||||||
|
cmp $0x11111111, %eax
|
||||||
|
jne _RegTest1Error
|
||||||
|
cmp $0x22222222, %ebx
|
||||||
|
jne _RegTest1Error
|
||||||
|
cmp $0x33333333, %ecx
|
||||||
|
jne _RegTest1Error
|
||||||
|
cmp $0x44444444, %edx
|
||||||
|
jne _RegTest1Error
|
||||||
|
cmp $0x55555555, %esi
|
||||||
|
jne _RegTest1Error
|
||||||
|
cmp $0x66666666, %edi
|
||||||
|
jne _RegTest1Error
|
||||||
|
|
||||||
|
|
||||||
|
.if configSUPPORT_FPU == 1
|
||||||
|
/* Loop checking the values originally loaded into the floating point
|
||||||
|
registers remain through the life of the task. */
|
||||||
|
push %eax /* push clobbered register. */
|
||||||
|
fldl dRegTest1_st7 /* st( 0 ) set to st( 7 ) value. */
|
||||||
|
fucomp %st( 7 ) /* Compare st( 0 ) with st( 7 ) and pop. */
|
||||||
|
fnstsw %ax /* Copy status word to ax. */
|
||||||
|
and $0x45, %ah /* Mask bits. */
|
||||||
|
xor $0x40, %ah /* test bits. */
|
||||||
|
jne _RegTest1Error
|
||||||
|
fldl dRegTest1_st6
|
||||||
|
fucomp %st( 6 )
|
||||||
|
fnstsw %ax
|
||||||
|
and $0x45, %ah
|
||||||
|
xor $0x40, %ah
|
||||||
|
jne _RegTest1Error
|
||||||
|
fldl dRegTest1_st5
|
||||||
|
fucomp %st( 5 )
|
||||||
|
fnstsw %ax
|
||||||
|
and $0x45, %ah
|
||||||
|
xor $0x40, %ah
|
||||||
|
jne _RegTest1Error
|
||||||
|
fldl dRegTest1_st4
|
||||||
|
fucomp %st( 4 )
|
||||||
|
fnstsw %ax
|
||||||
|
and $0x45, %ah
|
||||||
|
xor $0x40, %ah
|
||||||
|
jne _RegTest1Error
|
||||||
|
fldl dRegTest1_st3
|
||||||
|
fucomp %st( 3 )
|
||||||
|
fnstsw %ax
|
||||||
|
and $0x45, %ah
|
||||||
|
xor $0x40, %ah
|
||||||
|
jne _RegTest1Error
|
||||||
|
fldl dRegTest1_st2
|
||||||
|
fucomp %st( 2 )
|
||||||
|
fnstsw %ax
|
||||||
|
and $0x45, %ah
|
||||||
|
xor $0x40, %ah
|
||||||
|
jne _RegTest1Error
|
||||||
|
fldl dRegTest1_st1
|
||||||
|
fucomp %st( 1 )
|
||||||
|
fnstsw %ax
|
||||||
|
and $0x45, %ah
|
||||||
|
xor $0x40, %ah
|
||||||
|
jne _RegTest1Error
|
||||||
|
|
||||||
|
/* Restore clobbered register. */
|
||||||
|
pop %eax
|
||||||
|
.endif /* configSUPPORT_FPU */
|
||||||
|
|
||||||
|
/* Incrememnt the loop counter to prove this task has not gone into the
|
||||||
|
error null loop. */
|
||||||
|
add $1, ulRegTest1Counter
|
||||||
|
|
||||||
|
/* Loop again. */
|
||||||
|
jmp _RegTest1Loop
|
||||||
|
|
||||||
|
_RegTest1Error:
|
||||||
|
jmp .
|
||||||
|
.endfunc
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
.func vRegTest2
|
||||||
|
vRegTest2:
|
||||||
|
|
||||||
|
/* Set initial values into the general purpose registers. */
|
||||||
|
movl $0x10101010, %eax
|
||||||
|
movl $0x20202020, %ebx
|
||||||
|
movl $0x30303030, %ecx
|
||||||
|
movl $0x40404040, %edx
|
||||||
|
movl $0x50505050, %esi
|
||||||
|
movl $0x60606060, %edi
|
||||||
|
|
||||||
|
/* Set initial values into the floating point registers. */
|
||||||
|
.if configSUPPORT_FPU == 1
|
||||||
|
fldl dRegTest2_st7
|
||||||
|
fldl dRegTest2_st6
|
||||||
|
fldl dRegTest2_st5
|
||||||
|
fldl dRegTest2_st4
|
||||||
|
fldl dRegTest2_st3
|
||||||
|
fldl dRegTest2_st2
|
||||||
|
fldl dRegTest2_st1
|
||||||
|
.endif
|
||||||
|
|
||||||
|
_RegTest2Loop:
|
||||||
|
|
||||||
|
/* Loop checking the values originally loaded into the general purpose
|
||||||
|
registers remain through the life of the task. */
|
||||||
|
cmp $0x10101010, %eax
|
||||||
|
jne _RegTest2Error
|
||||||
|
cmp $0x20202020, %ebx
|
||||||
|
jne _RegTest2Error
|
||||||
|
cmp $0x30303030, %ecx
|
||||||
|
jne _RegTest2Error
|
||||||
|
cmp $0x40404040, %edx
|
||||||
|
jne _RegTest2Error
|
||||||
|
cmp $0x50505050, %esi
|
||||||
|
jne _RegTest2Error
|
||||||
|
cmp $0x60606060, %edi
|
||||||
|
jne _RegTest1Error
|
||||||
|
|
||||||
|
.if configSUPPORT_FPU == 1
|
||||||
|
/* Loop checking the values originally loaded into the floating point
|
||||||
|
registers remain through the life of the task. */
|
||||||
|
/* Loop checking the values originally loaded into the floating point
|
||||||
|
registers remain through the life of the task. */
|
||||||
|
push %eax /* push clobbered register. */
|
||||||
|
fldl dRegTest2_st7 /* st( 0 ) set to st( 7 ) value. */
|
||||||
|
fucomp %st( 7 ) /* Compare st( 0 ) with st( 7 ) and pop. */
|
||||||
|
fnstsw %ax /* Copy status word to ax. */
|
||||||
|
and $0x45, %ah /* Mask bits. */
|
||||||
|
xor $0x40, %ah /* test bits. */
|
||||||
|
jne _RegTest1Error
|
||||||
|
fldl dRegTest2_st6
|
||||||
|
fucomp %st( 6 )
|
||||||
|
fnstsw %ax
|
||||||
|
and $0x45, %ah
|
||||||
|
xor $0x40, %ah
|
||||||
|
jne _RegTest1Error
|
||||||
|
fldl dRegTest2_st5
|
||||||
|
fucomp %st( 5 )
|
||||||
|
fnstsw %ax
|
||||||
|
and $0x45, %ah
|
||||||
|
xor $0x40, %ah
|
||||||
|
jne _RegTest1Error
|
||||||
|
fldl dRegTest2_st4
|
||||||
|
fucomp %st( 4 )
|
||||||
|
fnstsw %ax
|
||||||
|
and $0x45, %ah
|
||||||
|
xor $0x40, %ah
|
||||||
|
jne _RegTest1Error
|
||||||
|
fldl dRegTest2_st3
|
||||||
|
fucomp %st( 3 )
|
||||||
|
fnstsw %ax
|
||||||
|
and $0x45, %ah
|
||||||
|
xor $0x40, %ah
|
||||||
|
jne _RegTest1Error
|
||||||
|
fldl dRegTest2_st2
|
||||||
|
fucomp %st( 2 )
|
||||||
|
fnstsw %ax
|
||||||
|
and $0x45, %ah
|
||||||
|
xor $0x40, %ah
|
||||||
|
jne _RegTest1Error
|
||||||
|
fldl dRegTest2_st1
|
||||||
|
fucomp %st( 1 )
|
||||||
|
fnstsw %ax
|
||||||
|
and $0x45, %ah
|
||||||
|
xor $0x40, %ah
|
||||||
|
jne _RegTest1Error
|
||||||
|
|
||||||
|
/* Restore clobbered register. */
|
||||||
|
pop %eax
|
||||||
|
|
||||||
|
.endif /* configSUPPORT_FPU */
|
||||||
|
|
||||||
|
/* Force a yield from one of the reg test tasks to increase coverage. */
|
||||||
|
call vGenerateYieldInterrupt
|
||||||
|
|
||||||
|
/* Increment the loop counter to prove this task has not entered the error
|
||||||
|
null loop. */
|
||||||
|
add $1, ulRegTest2Counter
|
||||||
|
jmp _RegTest2Loop
|
||||||
|
|
||||||
|
_RegTest2Error:
|
||||||
|
jmp .
|
||||||
|
|
||||||
|
.endfunc
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Purely for demonstration purposes, two of the HPET timers used by the
|
||||||
|
IntQueue test use the central interrupt handler, and timer 1 uses its own
|
||||||
|
assembly wrapper - which is defined below. See
|
||||||
|
http://www.freertos.org/RTOS_Intel_Quark_Galileo_GCC.html#interrupts for more
|
||||||
|
information. */
|
||||||
|
.func vApplicationHPETTimer1Wrapper
|
||||||
|
vApplicationHPETTimer1Wrapper:
|
||||||
|
|
||||||
|
portFREERTOS_INTERRUPT_ENTRY
|
||||||
|
call vHPETIRQHandler1
|
||||||
|
portFREERTOS_INTERRUPT_EXIT
|
||||||
|
|
||||||
|
.endfunc
|
||||||
|
|
||||||
|
.end
|
@ -0,0 +1,461 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* NOTE 1: This project provides two demo applications. A simple blinky style
|
||||||
|
* project, and a more comprehensive test and demo application. The
|
||||||
|
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
|
||||||
|
* between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
|
||||||
|
* in main.c. This file implements the comprehensive test and demo version.
|
||||||
|
*
|
||||||
|
* NOTE 2: This file only contains the source code that is specific to the
|
||||||
|
* full demo. Generic functions, such FreeRTOS hook functions, and functions
|
||||||
|
* required to configure the hardware, are defined in main.c.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* See http://www.FreeRTOS.org/RTOS_Intel_Quark_Galileo_GCC.html for usage
|
||||||
|
* instructions.
|
||||||
|
*
|
||||||
|
* main_full() creates all the demo application tasks and software timers, then
|
||||||
|
* starts the scheduler. The web documentation provides more details of the
|
||||||
|
* standard demo application tasks, which provide no particular functionality,
|
||||||
|
* but do provide a good example of how to use the FreeRTOS API.
|
||||||
|
*
|
||||||
|
* In addition to the standard demo tasks, the following tasks and tests are
|
||||||
|
* defined and/or created within this file:
|
||||||
|
*
|
||||||
|
* "Reg test" tasks - These fill both the core and floating point registers with
|
||||||
|
* known values, then check that each register maintains its expected value for
|
||||||
|
* the lifetime of the task. Each task uses a different set of values. The reg
|
||||||
|
* test tasks execute with a very low priority, so get preempted very
|
||||||
|
* frequently. A register containing an unexpected value is indicative of an
|
||||||
|
* error in the context switching mechanism.
|
||||||
|
*
|
||||||
|
* "Check" task - The check task period is set to five seconds. The task checks
|
||||||
|
* that all the standard demo tasks, and the register check tasks, are not only
|
||||||
|
* still executing, but are executing without reporting any errors. The check
|
||||||
|
* task toggles an LED on each iteration. If the LED toggles every 5 seconds
|
||||||
|
* then no errors have been found. If the LED toggles every 1 second then a
|
||||||
|
* potential error has been detected.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
|
/* Standard demo includes. */
|
||||||
|
#include "blocktim.h"
|
||||||
|
#include "flash_timer.h"
|
||||||
|
#include "semtest.h"
|
||||||
|
#include "GenQTest.h"
|
||||||
|
#include "QPeek.h"
|
||||||
|
#include "countsem.h"
|
||||||
|
#include "dynamic.h"
|
||||||
|
#include "QueueOverwrite.h"
|
||||||
|
#include "QueueSet.h"
|
||||||
|
#include "recmutex.h"
|
||||||
|
#include "EventGroupsDemo.h"
|
||||||
|
#include "death.h"
|
||||||
|
#include "TimerDemo.h"
|
||||||
|
#include "BlockQ.h"
|
||||||
|
#include "flop.h"
|
||||||
|
#include "TaskNotify.h"
|
||||||
|
#include "IntQueue.h"
|
||||||
|
|
||||||
|
/* Galileo includes. */
|
||||||
|
#include "galileo_support.h"
|
||||||
|
|
||||||
|
/* The rate at which the check task cycles if no errors have been detected, and
|
||||||
|
if a [potential] error has been detected. Increasing the toggle rate in the
|
||||||
|
presense of an error gives visual feedback of the system status. */
|
||||||
|
#define mainNO_ERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 5000UL )
|
||||||
|
#define mainERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 1000UL )
|
||||||
|
|
||||||
|
/* The priorities of the various demo application tasks. */
|
||||||
|
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||||
|
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||||
|
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
||||||
|
#define mainQUEUE_OVERWRITE_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
||||||
|
#define mainMATHS_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
||||||
|
|
||||||
|
/* The base period used by the timer test tasks. */
|
||||||
|
#define mainTIMER_TEST_PERIOD ( 50 )
|
||||||
|
|
||||||
|
/* Parameters that are passed into the check tasks for no other purpose other
|
||||||
|
than to check the port does this correctly. */
|
||||||
|
#define mainREG_TEST_1_PARAMETER ( 0x12345678UL )
|
||||||
|
#define mainREG_TEST_2_PARAMETER ( 0x87654321UL )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The function that implements the check task, as described at the top of this
|
||||||
|
* file.
|
||||||
|
*/
|
||||||
|
static void prvCheckTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Entry points for the register check tasks, as described at the top of this
|
||||||
|
* file.
|
||||||
|
*/
|
||||||
|
static void prvRegTest1Entry( void *pvParameters );
|
||||||
|
static void prvRegTest2Entry( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The implementation of the register check tasks, which are implemented in
|
||||||
|
* RegTest.S. These functions are called by prvRegTest1Entry() and
|
||||||
|
* prvRegTest2Entry() respectively.
|
||||||
|
*/
|
||||||
|
extern void vRegTest1( void );
|
||||||
|
extern void vRegTest2( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Constants used by the register check tasks when checking the FPU registers. */
|
||||||
|
const double dRegTest1_st7 = 7.0, dRegTest1_st6 = 6.0, dRegTest1_st5 = 5.0, dRegTest1_st4 = 4.0, dRegTest1_st3 = 3.0, dRegTest1_st2 = 2.0, dRegTest1_st1 = 1.0;
|
||||||
|
const double dRegTest2_st7 = 700.0, dRegTest2_st6 = 600.0, dRegTest2_st5 = 500.0, dRegTest2_st4 = 400.0, dRegTest2_st3 = 300.0, dRegTest2_st2 = 200.0, dRegTest2_st1 = 100.0;
|
||||||
|
|
||||||
|
/* Counters used by the register check tasks to indicate that they are still
|
||||||
|
executing without having discovered any errors. */
|
||||||
|
volatile uint32_t ulRegTest1Counter, ulRegTest2Counter;
|
||||||
|
volatile uint32_t ulCheckLoops = 0;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* See http://www.FreeRTOS.org/RTOS_Intel_Quark_Galileo_GCC.html for usage
|
||||||
|
instructions. */
|
||||||
|
void main_full( void )
|
||||||
|
{
|
||||||
|
/* Create all the other standard demo tasks. */
|
||||||
|
vCreateBlockTimeTasks();
|
||||||
|
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
|
||||||
|
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
|
||||||
|
vStartQueuePeekTasks();
|
||||||
|
vStartCountingSemaphoreTasks();
|
||||||
|
vStartDynamicPriorityTasks();
|
||||||
|
vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_TASK_PRIORITY );
|
||||||
|
vStartQueueSetTasks();
|
||||||
|
vStartRecursiveMutexTasks();
|
||||||
|
vStartEventGroupTasks();
|
||||||
|
vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
|
||||||
|
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
|
||||||
|
vStartTaskNotifyTask();
|
||||||
|
vStartInterruptQueueTasks();
|
||||||
|
|
||||||
|
#if configSUPPORT_FPU == 1
|
||||||
|
{
|
||||||
|
vStartMathTasks( mainMATHS_TASK_PRIORITY );
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_FPU */
|
||||||
|
|
||||||
|
/* Create the 'check' task, as described at the top of this file. */
|
||||||
|
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE * 2, NULL, configMAX_PRIORITIES - 1, NULL );
|
||||||
|
|
||||||
|
/* Create the register test tasks, as described at the top of this file. */
|
||||||
|
xTaskCreate( prvRegTest1Entry, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) mainREG_TEST_1_PARAMETER, tskIDLE_PRIORITY, NULL );
|
||||||
|
xTaskCreate( prvRegTest2Entry, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) mainREG_TEST_2_PARAMETER, tskIDLE_PRIORITY, NULL );
|
||||||
|
|
||||||
|
/* Death tasks must be created last as they check the number of tasks
|
||||||
|
running against the number of tasks expected to be running as part of their
|
||||||
|
sanity checks. */
|
||||||
|
vCreateSuicidalTasks( tskIDLE_PRIORITY );
|
||||||
|
|
||||||
|
/* Display HPET Information (Disable in HPET.H). */
|
||||||
|
vCreateHPETInfoUpdateTask();
|
||||||
|
|
||||||
|
/* Start the scheduler itself. */
|
||||||
|
vTaskStartScheduler();
|
||||||
|
|
||||||
|
/* If all is well, the scheduler will now be running, and the following line
|
||||||
|
will never be reached. If the following line does execute, then there was
|
||||||
|
insufficient FreeRTOS heap memory available for the idle and/or timer tasks
|
||||||
|
to be created. See the memory management section on the FreeRTOS web site
|
||||||
|
for more details. */
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvRegTest1Entry( void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Remove compiler warning if configASSERT() is not defined. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Check the parameter is passed in correctly. */
|
||||||
|
configASSERT( ( ( uint32_t) pvParameters ) == mainREG_TEST_1_PARAMETER );
|
||||||
|
|
||||||
|
/* Tell FreeRTOS that this task needs a floating point context. */
|
||||||
|
portTASK_USES_FLOATING_POINT();
|
||||||
|
|
||||||
|
/* Call the assembly file routine that performs the 'reg test' functionality
|
||||||
|
as described at the top of this file. */
|
||||||
|
vRegTest1();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvRegTest2Entry( void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Remove compiler warning if configASSERT() is not defined. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Check the parameter is passed in correctly. */
|
||||||
|
configASSERT( ( ( uint32_t) pvParameters ) == mainREG_TEST_2_PARAMETER );
|
||||||
|
|
||||||
|
/* Tell FreeRTOS that this task needs a floating point context. */
|
||||||
|
portTASK_USES_FLOATING_POINT();
|
||||||
|
|
||||||
|
/* Call the assembly file routine that performs the 'reg test' functionality
|
||||||
|
as described at the top of this file. */
|
||||||
|
vRegTest2();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCheckTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
uint32_t ulLastRegTest1Counter = 0UL, ulLastRegTest2Counter = 0UL;
|
||||||
|
uint32_t ulErrorOccurred, ulElapsedTimeInSeconds = 0UL;
|
||||||
|
TickType_t xLastExpireTime, xBlockTime = mainNO_ERROR_CHECK_TASK_PERIOD;
|
||||||
|
BaseType_t xErrorFlag = pdFALSE;
|
||||||
|
|
||||||
|
/* Avoid compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Initialise the last expire time to the current time. */
|
||||||
|
xLastExpireTime = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* Message to wait for an update - first update won't happen for X seconds. */
|
||||||
|
g_printf_rcc( 5, 2, DEFAULT_SCREEN_COLOR, "Starting task check loop - Please wait for a status update." );
|
||||||
|
g_printf_rcc( 6, 2, DEFAULT_SCREEN_COLOR, "No task errors encountered." );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
vTaskDelayUntil( &xLastExpireTime, xBlockTime );
|
||||||
|
ulElapsedTimeInSeconds += xBlockTime;
|
||||||
|
|
||||||
|
/* Have any of the standard demo tasks detected an error in their
|
||||||
|
operation? If so, latch the offending test in a bit map so it can be
|
||||||
|
printed to the terminal. Once one error has occurred the cycle rate is
|
||||||
|
increased to increase the rate at which the LED toggles, which can cause
|
||||||
|
further errors to be detected (as some tests will not expect the
|
||||||
|
increased cycle rate). */
|
||||||
|
|
||||||
|
ulErrorOccurred = 0UL;
|
||||||
|
|
||||||
|
if( xAreQueuePeekTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 0UL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 1UL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 2UL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 3UL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 4UL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 5UL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xIsQueueOverwriteTaskStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 6UL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreQueueSetTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 7UL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 8UL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreEventGroupTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 9UL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xIsCreateTaskStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 10UL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreTimerDemoTasksStillRunning( xBlockTime ) != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 11UL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreBlockingQueuesStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 12UL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreTaskNotificationTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 1UL << 13UL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreIntQueueTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 1UL << 14UL );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configSUPPORT_FPU == 1
|
||||||
|
{
|
||||||
|
if( xAreMathsTaskStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 15UL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_FPU */
|
||||||
|
|
||||||
|
/* Check the register test tasks are still looping. */
|
||||||
|
if( ulRegTest1Counter == ulLastRegTest1Counter )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 16UL );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulLastRegTest1Counter = ulRegTest1Counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulRegTest2Counter == ulLastRegTest2Counter )
|
||||||
|
{
|
||||||
|
ulErrorOccurred |= ( 0x01UL << 17UL );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulLastRegTest2Counter = ulRegTest2Counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulErrorOccurred != 0UL )
|
||||||
|
{
|
||||||
|
/* Decrease the block time, which will increase the rate at
|
||||||
|
which the LED blinks - and in so doing - give visual feedback of
|
||||||
|
the error status. */
|
||||||
|
xBlockTime = mainERROR_CHECK_TASK_PERIOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print the hex bit pattern, time, and the loop number - just to make
|
||||||
|
sure the task is still cycling. */
|
||||||
|
g_printf_rcc( 5, 2, DEFAULT_SCREEN_COLOR,
|
||||||
|
"Status code: 0x%08x at task check time : %8ds, loop #: %8d\r",
|
||||||
|
ulErrorOccurred, ( ulElapsedTimeInSeconds / 1000 ), ( ulCheckLoops + 1 ) );
|
||||||
|
|
||||||
|
/* Print the current free heap size and the minimum ever free heap
|
||||||
|
size. */
|
||||||
|
g_printf_rcc( 6, 2, DEFAULT_SCREEN_COLOR,
|
||||||
|
"Current free heap: %d bytes, Min. free heap: %d bytes\r",
|
||||||
|
xPortGetFreeHeapSize(), xPortGetMinimumEverFreeHeapSize() );
|
||||||
|
|
||||||
|
/* Show the first error that occurred on a separate line. */
|
||||||
|
if( ( xErrorFlag == pdFALSE ) && ( ulErrorOccurred != pdFALSE ) )
|
||||||
|
{
|
||||||
|
xErrorFlag = pdTRUE;
|
||||||
|
g_printf_rcc( 7, 2, ANSI_COLOR_RED,
|
||||||
|
"Error code: 0x%08x at check time : %8ds (First Error), loop#: %8d \r",
|
||||||
|
ulErrorOccurred, ( ulElapsedTimeInSeconds / 1000 ), ( ulCheckLoops + 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flash the LED */
|
||||||
|
ulBlinkLED();
|
||||||
|
|
||||||
|
/* Crude Overflow check to keep printf() statements <= 8 digits long */
|
||||||
|
ulCheckLoops++;
|
||||||
|
if( ulCheckLoops > 10000000UL )
|
||||||
|
{
|
||||||
|
ulCheckLoops = 0UL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -0,0 +1,5 @@
|
|||||||
|
[{000214A0-0000-0000-C000-000000000046}]
|
||||||
|
Prop3=19,2
|
||||||
|
[InternetShortcut]
|
||||||
|
URL=http://www.freertos.org/RTOS_Intel_Quark_Galileo_GCC.html
|
||||||
|
IDList=
|
@ -0,0 +1,890 @@
|
|||||||
|
/*--------------------------------------------------------------------
|
||||||
|
Copyright(c) 2015 Intel Corporation. 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 Intel Corporation nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
--------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Any required includes
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "GPIO_I2C.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Any required local definitions
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL (void *)0
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Function prototypes
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static void vGalileoRouteLEDPins(void);
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Static variables
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static struct BOARD_GPIO_CONTROLLER_CONFIG GpioConfig;
|
||||||
|
static struct BOARD_LEGACY_GPIO_CONFIG LegacyGpioConfig;
|
||||||
|
|
||||||
|
static uint32_t LegacyGpioBase = 0;
|
||||||
|
static uint32_t IohGpioBase = 0;
|
||||||
|
static uint32_t I2CGpioBase = 0;
|
||||||
|
|
||||||
|
static uint32_t bGalileoGPIOInitialized = FALSE;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* GPIO support functions
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static uint32_t pciIOread32(uint32_t addr)
|
||||||
|
{
|
||||||
|
outl(IO_PCI_ADDRESS_PORT, addr);
|
||||||
|
uint32_t data = inl(IO_PCI_DATA_PORT);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void pciIOwrite32(uint32_t addr, uint32_t IO_data)
|
||||||
|
{
|
||||||
|
outl(IO_PCI_ADDRESS_PORT, addr);
|
||||||
|
outl(IO_PCI_DATA_PORT, IO_data );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int32_t uiGalileoGPIORead(uint32_t Offset, uint8_t UseMask)
|
||||||
|
{
|
||||||
|
// Keep reserved bits [31:8]
|
||||||
|
if (UseMask)
|
||||||
|
return *((volatile uint32_t *) (uintn_t)(IohGpioBase + Offset)) & 0xFFFFFF00;
|
||||||
|
else
|
||||||
|
return *((volatile uint32_t *) (uintn_t)(IohGpioBase + Offset));
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vGalileoGPIOWrite(uint32_t Offset, uint32_t WriteData32)
|
||||||
|
{
|
||||||
|
uint32_t Data32 = uiGalileoGPIORead(Offset, true);
|
||||||
|
if (Offset != GPIO_INTSTATUS)
|
||||||
|
Data32 |= (WriteData32 & 0x000FFFFF);
|
||||||
|
*((volatile uint32_t *) (uintn_t)(IohGpioBase + Offset)) = Data32;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int32_t uiGalileoLegacyGPIOPCIRead(uint32_t addr, uint32_t Mask)
|
||||||
|
{
|
||||||
|
// Keep reserved bits (Mask Varies)
|
||||||
|
return pciIOread32(addr) & Mask;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vGalileoLegacyGPIOPCIWrite(uint32_t addr, uint32_t WriteData32, uint32_t Mask)
|
||||||
|
{
|
||||||
|
uint32_t Data32 = uiGalileoLegacyGPIOPCIRead(addr, Mask);
|
||||||
|
Data32 |= (WriteData32 & ~Mask);
|
||||||
|
pciIOwrite32(addr, Data32);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int32_t uiGalileoLegacyGPIOPortRead(uint32_t addr, uint32_t Mask)
|
||||||
|
{
|
||||||
|
// Keep reserved bits (Mask Varies)
|
||||||
|
return inl(addr) & Mask;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vGalileoLegacyGPIOPortRMW(uint32_t addr, uint32_t WriteData32, uint32_t Mask)
|
||||||
|
{
|
||||||
|
uint32_t Data32 = uiGalileoLegacyGPIOPortRead(addr, Mask);
|
||||||
|
Data32 |= (WriteData32 & ~Mask);
|
||||||
|
outl(addr, Data32);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Controller initialization functions
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void vGalileoInitializeLegacyGPIO(void)
|
||||||
|
{
|
||||||
|
// Read Register Default Values into Structure
|
||||||
|
struct BOARD_LEGACY_GPIO_CONFIG LegacyGPIOConfigTable[] =
|
||||||
|
{ PLATFORM_LEGACY_GPIO_CONFIG_DEFINITION };
|
||||||
|
|
||||||
|
// BDF for Legacy GPIO (from the Quark Datasheet)
|
||||||
|
uint8_t Bus = LEGACY_GPIO_BUS_NUMBER;
|
||||||
|
uint8_t Device = LEGACY_GPIO_DEVICE_NUMBER;
|
||||||
|
uint8_t Func = LEGACY_GPIO_FUNCTION_NUMBER;
|
||||||
|
|
||||||
|
// Get PCI Configuration IO Address
|
||||||
|
LegacyGpioBase =
|
||||||
|
uiGalileoLegacyGPIOPCIRead(IO_PCI_ADDRESS(Bus, Device, Func, R_QNC_LPC_GBA_BASE), B_QNC_LPC_GPA_BASE_MASK);
|
||||||
|
|
||||||
|
// Quiet compiler by doing a legacy GPIO write
|
||||||
|
uint32_t PciCmd = uiGalileoLegacyGPIOPCIRead((LegacyGpioBase + PCI_REG_PCICMD), 0xFFFFFFFF);
|
||||||
|
vGalileoLegacyGPIOPCIWrite((LegacyGpioBase + PCI_REG_PCICMD), (PciCmd | 0x7), 0xFFFFFFFF);
|
||||||
|
|
||||||
|
// Setup Structure
|
||||||
|
LegacyGpioConfig = LegacyGPIOConfigTable[0];
|
||||||
|
|
||||||
|
// Update values
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_CGEN_CORE_WELL, LegacyGpioConfig.CoreWellEnable, 0xFFFFFFFC);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_CGIO_CORE_WELL, LegacyGpioConfig.CoreWellIoSelect, 0xFFFFFFFC);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_CGLVL_CORE_WELL, LegacyGpioConfig.CoreWellLvlForInputOrOutput, 0xFFFFFFFC);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_CGTPE_CORE_WELL, LegacyGpioConfig.CoreWellTriggerPositiveEdge, 0xFFFFFFFC);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_CGTNE_CORE_WELL, LegacyGpioConfig.CoreWellTriggerNegativeEdge, 0xFFFFFFFC);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_CGGPE_CORE_WELL, LegacyGpioConfig.ResumeWellGPEEnable, 0xFFFFFFFC);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_CGSMI_CORE_WELL, LegacyGpioConfig.ResumeWellSMIEnable, 0xFFFFFFFC);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_CGEN_CORE_WELL, LegacyGpioConfig.CoreWellTriggerStatus, 0xFFFFFFFC);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_CNMIEN_CORE_WELL, LegacyGpioConfig.ResumeWellNMIEnable, 0xFFFFFFFC);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_RGEN_RESUME_WELL, LegacyGpioConfig.ResumeWellEnable, 0xFFFFFFC0);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_RGIO_RESUME_WELL, LegacyGpioConfig.ResumeWellIoSelect, 0xFFFFFFC0);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_RGLVL_RESUME_WELL, LegacyGpioConfig.ResumeWellLvlForInputOrOutput, 0xFFFFFFC0);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_RGTPE_RESUME_WELL, LegacyGpioConfig.ResumeWellTriggerPositiveEdge, 0xFFFFFFC0);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_RGTNE_RESUME_WELL, LegacyGpioConfig.ResumeWellTriggerNegativeEdge, 0xFFFFFFC0);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_RGGPE_RESUME_WELL, LegacyGpioConfig.CoreWellGPEEnable, 0xFFFFFFC0);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_RGSMI_RESUME_WELL, LegacyGpioConfig.CoreWellSMIEnable, 0xFFFFFFC0);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_RGTS_RESUME_WELL, LegacyGpioConfig.ResumeWellTriggerStatus, 0xFFFFFFC0);
|
||||||
|
vGalileoLegacyGPIOPortRMW(LegacyGpioBase + R_QNC_GPIO_RNMIEN_RESUME_WELL, LegacyGpioConfig.CoreWellNMIEnable, 0xFFFFFFC0);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vGalileoInitializeGpioController(void)
|
||||||
|
{
|
||||||
|
// Read Register Default Values into Structure
|
||||||
|
struct BOARD_GPIO_CONTROLLER_CONFIG BoardGpioControllerConfigTable[] =
|
||||||
|
{ PLATFORM_GPIO_CONTROLLER_CONFIG_DEFINITION };
|
||||||
|
|
||||||
|
// BDF for I2C Controller (from the Quark Datasheet)
|
||||||
|
uint8_t Bus = IOH_I2C_GPIO_BUS_NUMBER;
|
||||||
|
uint8_t Device = IOH_I2C_GPIO_DEVICE_NUMBER;
|
||||||
|
uint8_t Func = IOH_I2C_GPIO_FUNCTION_NUMBER;
|
||||||
|
|
||||||
|
// Get PCI Configuration MMIO Address
|
||||||
|
uint32_t gpio_controller_base = MMIO_PCI_ADDRESS(Bus, Device, Func, 0);
|
||||||
|
|
||||||
|
// Get Vendor and Device IDs
|
||||||
|
uint16_t PciVid = mem_read(gpio_controller_base, PCI_REG_VID, 2);
|
||||||
|
uint16_t PciDid = mem_read(gpio_controller_base, PCI_REG_DID, 2);
|
||||||
|
|
||||||
|
// Check for valid VID and DID
|
||||||
|
if((PciVid == V_IOH_I2C_GPIO_VENDOR_ID) && (PciDid == V_IOH_I2C_GPIO_DEVICE_ID))
|
||||||
|
{
|
||||||
|
// Read PCICMD
|
||||||
|
uint8_t PciCmd = mem_read(gpio_controller_base, PCI_REG_PCICMD, 1);
|
||||||
|
// Enable Bus Master(Bit2), MMIO Space(Bit1) & I/O Space(Bit0)
|
||||||
|
mem_write(gpio_controller_base, PCI_REG_PCICMD, 1, (PciCmd | 0x7));
|
||||||
|
// Read MEM_BASE
|
||||||
|
IohGpioBase = mem_read(gpio_controller_base, R_IOH_GPIO_MEMBAR, 4);
|
||||||
|
// Setup Structure
|
||||||
|
GpioConfig = BoardGpioControllerConfigTable[0];
|
||||||
|
// IEN- Interrupt Enable Register
|
||||||
|
vGalileoGPIOWrite(GPIO_INTEN, GpioConfig.IntEn);
|
||||||
|
// ISTATUS- Interrupt Status Register
|
||||||
|
vGalileoGPIOWrite(GPIO_INTSTATUS, 0);
|
||||||
|
// GPIO SWPORTA Data Register - GPIO_SWPORTA_DR
|
||||||
|
vGalileoGPIOWrite(GPIO_SWPORTA_DR, GpioConfig.PortADR);
|
||||||
|
// GPIO SWPORTA Data Direction Register - GPIO_SWPORTA_DDR
|
||||||
|
vGalileoGPIOWrite(GPIO_SWPORTA_DDR, GpioConfig.PortADir);
|
||||||
|
// Interrupt Mask Register - GPIO_INTMASK
|
||||||
|
vGalileoGPIOWrite(GPIO_INTMASK, GpioConfig.IntMask);
|
||||||
|
// Interrupt Level Type Register - GPIO_INTTYPE_LEVEL
|
||||||
|
vGalileoGPIOWrite(GPIO_INTTYPE_LEVEL, GpioConfig.IntType);
|
||||||
|
// Interrupt Polarity Type Register - GPIO_INT_POLARITY
|
||||||
|
vGalileoGPIOWrite(GPIO_INT_POLARITY, GpioConfig.IntPolarity);
|
||||||
|
// Interrupt Debounce Type Register - GPIO_DEBOUNCE
|
||||||
|
vGalileoGPIOWrite(GPIO_DEBOUNCE, GpioConfig.Debounce);
|
||||||
|
// Interrupt Clock Synchronization Register - GPIO_LS_SYNC
|
||||||
|
vGalileoGPIOWrite(GPIO_LS_SYNC, GpioConfig.LsSync);
|
||||||
|
bGalileoGPIOInitialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* I/O direction and level setting functions
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void vGalileoSetGPIOBitDirection(uint32_t GPIONumber, uint32_t Direction)
|
||||||
|
{
|
||||||
|
/* Check Range. */
|
||||||
|
if(GPIONumber <= 9)
|
||||||
|
{
|
||||||
|
/* setup gpio direction. */
|
||||||
|
if (bGalileoGPIOInitialized)
|
||||||
|
{
|
||||||
|
if(Direction == GPIO_OUTPUT)
|
||||||
|
GpioConfig.PortADir |= (1 << GPIONumber);
|
||||||
|
else
|
||||||
|
GpioConfig.PortADir &= ~(1 << GPIONumber);
|
||||||
|
vGalileoGPIOWrite(GPIO_SWPORTA_DDR, GpioConfig.PortADir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vGalileoSetGPIOBitLevel(uint32_t GPIONumber, uint32_t Level)
|
||||||
|
{
|
||||||
|
/* Check Range. */
|
||||||
|
if(GPIONumber <= 9)
|
||||||
|
{
|
||||||
|
/* Set the bit high or low. */
|
||||||
|
if (bGalileoGPIOInitialized)
|
||||||
|
{
|
||||||
|
// 1 for on, 0 for off.
|
||||||
|
if (Level == HIGH)
|
||||||
|
GpioConfig.PortADR |= (1 << GPIONumber);
|
||||||
|
else
|
||||||
|
GpioConfig.PortADR &= ~(1 << GPIONumber);
|
||||||
|
vGalileoGPIOWrite(GPIO_SWPORTA_DR, GpioConfig.PortADR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void LegacyGpioSetLevel(uint32_t RegOffset, uint32_t GpioNum, uint8_t HighLevel)
|
||||||
|
{
|
||||||
|
uint32_t RegValue;
|
||||||
|
uint32_t legacy_gpio_base;
|
||||||
|
uint32_t GpioNumMask;
|
||||||
|
uint8_t Bus = LEGACY_GPIO_BUS_NUMBER;
|
||||||
|
uint8_t Device = LEGACY_GPIO_DEVICE_NUMBER;
|
||||||
|
uint8_t Func = LEGACY_GPIO_FUNCTION_NUMBER;
|
||||||
|
|
||||||
|
// Get PCI Configuration IO Address
|
||||||
|
legacy_gpio_base =
|
||||||
|
uiGalileoLegacyGPIOPCIRead(IO_PCI_ADDRESS(Bus, Device, Func, R_QNC_LPC_GBA_BASE), B_QNC_LPC_GPA_BASE_MASK);
|
||||||
|
|
||||||
|
// Read register (Port I/O )
|
||||||
|
RegValue = inl(legacy_gpio_base + RegOffset);
|
||||||
|
|
||||||
|
// Set Data and mask
|
||||||
|
GpioNumMask = (1 << GpioNum);
|
||||||
|
if (HighLevel)
|
||||||
|
RegValue |= (GpioNumMask);
|
||||||
|
else
|
||||||
|
RegValue &= ~(GpioNumMask);
|
||||||
|
|
||||||
|
// Write the data (Port I/O )
|
||||||
|
outl((legacy_gpio_base + RegOffset), RegValue);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vGalileoLegacyGPIOInitializationForLED(void)
|
||||||
|
{
|
||||||
|
// Setup multiplexers to route GPIO_SUS<5> to LED
|
||||||
|
vGalileoRouteLEDPins();
|
||||||
|
|
||||||
|
// Set GPIO_SUS<5> as output
|
||||||
|
LegacyGpioSetLevel (R_QNC_GPIO_RGIO_RESUME_WELL,
|
||||||
|
GALILEO_GEN2_FLASH_UPDATE_LED_RESUMEWELL_GPIO, GPIO_OUTPUT);
|
||||||
|
|
||||||
|
// Set GPIO_SUS<5> level to low
|
||||||
|
LegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL,
|
||||||
|
GALILEO_GEN2_FLASH_UPDATE_LED_RESUMEWELL_GPIO, LOW);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vGalileoBlinkLEDUsingLegacyGPIO(uint32_t Level)
|
||||||
|
{
|
||||||
|
LegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL,
|
||||||
|
GALILEO_GEN2_FLASH_UPDATE_LED_RESUMEWELL_GPIO, Level);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* I2C support functions
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static inline uint64_t rdtsc(void)
|
||||||
|
{
|
||||||
|
uint32_t lo, hi;
|
||||||
|
uint64_t tsc;
|
||||||
|
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
|
||||||
|
tsc = hi;
|
||||||
|
tsc <<= 32;
|
||||||
|
tsc |= lo;
|
||||||
|
return tsc;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vMicroSecondDelay(uint32_t DelayTime)
|
||||||
|
{
|
||||||
|
uint64_t diff_in_us = 0;
|
||||||
|
uint64_t cpufreq_in_mhz = 400;
|
||||||
|
uint64_t tsc_start = rdtsc();
|
||||||
|
uint64_t tsc_current = tsc_start;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
diff_in_us = ((tsc_current - tsc_start) / cpufreq_in_mhz);
|
||||||
|
tsc_current = rdtsc();
|
||||||
|
}
|
||||||
|
while (diff_in_us < (uint64_t) DelayTime);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vMilliSecondDelay(uint32_t DelayTime)
|
||||||
|
{
|
||||||
|
vMicroSecondDelay (DelayTime * 1000);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static uintn_t GetI2CIoPortBaseAddress(void)
|
||||||
|
{
|
||||||
|
uint8_t Bus = IOH_I2C_GPIO_BUS_NUMBER;
|
||||||
|
uint8_t Device = IOH_I2C_GPIO_DEVICE_NUMBER;
|
||||||
|
int8_t Func = IOH_I2C_GPIO_FUNCTION_NUMBER;
|
||||||
|
uint32_t I2C_controller_base = MMIO_PCI_ADDRESS(Bus, Device, Func, 0);
|
||||||
|
uintn_t I2CIoPortBaseAddress = mem_read(I2C_controller_base, R_IOH_I2C_MEMBAR, 4);
|
||||||
|
return I2CIoPortBaseAddress;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void EnableI2CMmioSpace(void)
|
||||||
|
{
|
||||||
|
uint8_t Bus = IOH_I2C_GPIO_BUS_NUMBER;
|
||||||
|
uint8_t Device = IOH_I2C_GPIO_DEVICE_NUMBER;
|
||||||
|
uint8_t Func = IOH_I2C_GPIO_FUNCTION_NUMBER;
|
||||||
|
uint32_t I2C_controller_base = MMIO_PCI_ADDRESS(Bus, Device, Func, 0);
|
||||||
|
uint8_t PciCmd = mem_read(I2C_controller_base, PCI_REG_PCICMD, 1);
|
||||||
|
mem_write(I2C_controller_base, PCI_REG_PCICMD, 1, (PciCmd | 0x7));
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void DisableI2CController(void)
|
||||||
|
{
|
||||||
|
uintn_t I2CIoPortBaseAddress;
|
||||||
|
uint32_t Addr;
|
||||||
|
uint32_t Data;
|
||||||
|
uint8_t PollCount = 0;
|
||||||
|
|
||||||
|
// Get I2C Memory Mapped registers base address.
|
||||||
|
I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
|
||||||
|
|
||||||
|
// Disable the I2C Controller by setting IC_ENABLE.ENABLE to zero
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_ENABLE;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
Data &= ~B_I2C_REG_ENABLE;
|
||||||
|
*((volatile uint32_t *) (uintn_t)(Addr)) = Data;
|
||||||
|
|
||||||
|
// Read the IC_ENABLE_STATUS.IC_EN Bit to check if Controller is disabled
|
||||||
|
Data = 0xFF;
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_ENABLE_STATUS;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr)) & I2C_REG_ENABLE_STATUS;
|
||||||
|
while (Data != 0)
|
||||||
|
{
|
||||||
|
// Poll the IC_ENABLE_STATUS.IC_EN Bit to check if Controller is disabled, until timeout (TI2C_POLL*MAX_T_POLL_COUNT).
|
||||||
|
if (++PollCount >= MAX_T_POLL_COUNT)
|
||||||
|
break;
|
||||||
|
vMicroSecondDelay(TI2C_POLL);
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
Data &= I2C_REG_ENABLE_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read IC_CLR_INTR register to automatically clear the combined interrupt,
|
||||||
|
// all individual interrupts and the IC_TX_ABRT_SOURCE register.
|
||||||
|
if (PollCount < MAX_T_POLL_COUNT)
|
||||||
|
{
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_CLR_INT;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void EnableI2CController(void)
|
||||||
|
{
|
||||||
|
uintn_t I2CIoPortBaseAddress;
|
||||||
|
uint32_t Addr;
|
||||||
|
uint32_t Data;
|
||||||
|
|
||||||
|
// Get I2C Memory Mapped registers base address.
|
||||||
|
I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
|
||||||
|
|
||||||
|
// Enable the I2C Controller by setting IC_ENABLE.ENABLE to 1
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_ENABLE;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
Data |= B_I2C_REG_ENABLE;
|
||||||
|
*((volatile uint32_t *) (uintn_t)(Addr)) = Data;
|
||||||
|
|
||||||
|
// Clear overflow and abort error status bits before transactions.
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_CLR_RX_OVER;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_CLR_TX_OVER;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_CLR_TX_ABRT;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static uint32_t InitializeInternal(I2C_ADDR_MODE AddrMode)
|
||||||
|
{
|
||||||
|
uintn_t I2CIoPortBaseAddress;
|
||||||
|
uintn_t Addr;
|
||||||
|
uint32_t Data;
|
||||||
|
uint32_t Status = 0;
|
||||||
|
|
||||||
|
// Enable access to I2C Controller MMIO space.
|
||||||
|
EnableI2CMmioSpace ();
|
||||||
|
|
||||||
|
// Disable I2C Controller initially
|
||||||
|
DisableI2CController ();
|
||||||
|
|
||||||
|
// Get I2C Memory Mapped registers base address.
|
||||||
|
I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
|
||||||
|
|
||||||
|
// Clear START_DET
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_CLR_START_DET;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
Data &= ~B_I2C_REG_CLR_START_DET;
|
||||||
|
*((volatile uint32_t *) (uintn_t)(Addr)) = Data;
|
||||||
|
|
||||||
|
// Clear STOP_DET
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_CLR_STOP_DET;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
Data &= ~B_I2C_REG_CLR_STOP_DET;
|
||||||
|
*((volatile uint32_t *) (uintn_t)(Addr)) = Data;
|
||||||
|
|
||||||
|
// Set addressing mode to user defined (7 or 10 bit) and
|
||||||
|
// speed mode to that defined by PCD (standard mode default).
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_CON;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
|
||||||
|
// Set Addressing Mode
|
||||||
|
if (AddrMode == EfiI2CSevenBitAddrMode)
|
||||||
|
Data &= ~B_I2C_REG_CON_10BITADD_MASTER;
|
||||||
|
else
|
||||||
|
Data |= B_I2C_REG_CON_10BITADD_MASTER;
|
||||||
|
|
||||||
|
// Set Speed Mode
|
||||||
|
Data &= ~B_I2C_REG_CON_SPEED;
|
||||||
|
|
||||||
|
// Default to slow mode
|
||||||
|
Data |= BIT1;
|
||||||
|
*((volatile uint32_t *) (uintn_t)(Addr)) = Data;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void I2cEntry(uint16_t *SaveCmdPtr, uint32_t *SaveBar0Ptr)
|
||||||
|
{
|
||||||
|
uint8_t Bus = IOH_I2C_GPIO_BUS_NUMBER;
|
||||||
|
uint8_t Device = IOH_I2C_GPIO_DEVICE_NUMBER;
|
||||||
|
uint8_t Func = IOH_I2C_GPIO_FUNCTION_NUMBER;
|
||||||
|
uint32_t I2C_controller_base = MMIO_PCI_ADDRESS(Bus, Device, Func, 0);
|
||||||
|
|
||||||
|
I2CGpioBase = mem_read(I2C_controller_base, R_IOH_I2C_MEMBAR, 4);
|
||||||
|
*SaveBar0Ptr = I2CGpioBase;
|
||||||
|
if (((*SaveBar0Ptr) & B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK) == 0)
|
||||||
|
{
|
||||||
|
mem_write(I2C_controller_base, R_IOH_I2C_MEMBAR, 4, IO_PCI_ADDRESS(Bus, Device, Func, 0));
|
||||||
|
// also Save Cmd Register, Setup by InitializeInternal later during xfers.
|
||||||
|
*SaveCmdPtr = mem_read(I2C_controller_base, PCI_REG_PCICMD, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void I2cExit(uint16_t SaveCmd, uint32_t SaveBar0)
|
||||||
|
{
|
||||||
|
if ((SaveBar0 & B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK) == 0)
|
||||||
|
{
|
||||||
|
uint8_t Bus = IOH_I2C_GPIO_BUS_NUMBER;
|
||||||
|
uint8_t Device = IOH_I2C_GPIO_DEVICE_NUMBER;
|
||||||
|
uint8_t Func = IOH_I2C_GPIO_FUNCTION_NUMBER;
|
||||||
|
uint32_t I2C_controller_base = MMIO_PCI_ADDRESS(Bus, Device, Func, 0);
|
||||||
|
mem_write(I2C_controller_base, PCI_REG_PCICMD, 1, SaveCmd);
|
||||||
|
mem_write(I2C_controller_base, R_IOH_I2C_MEMBAR, 4, SaveBar0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static uint32_t WaitForStopDet(void)
|
||||||
|
{
|
||||||
|
uintn_t I2CIoPortBaseAddress;
|
||||||
|
uint32_t Addr;
|
||||||
|
uint32_t Data;
|
||||||
|
uint32_t PollCount = 0;
|
||||||
|
uint32_t Status = 0;
|
||||||
|
|
||||||
|
// Get I2C Memory Mapped registers base address.
|
||||||
|
I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
|
||||||
|
|
||||||
|
// Wait for STOP Detect.
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
if ((Data & I2C_REG_RAW_INTR_STAT_TX_ABRT) != 0)
|
||||||
|
{
|
||||||
|
Status = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((Data & I2C_REG_RAW_INTR_STAT_TX_OVER) != 0)
|
||||||
|
{
|
||||||
|
Status = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((Data & I2C_REG_RAW_INTR_STAT_RX_OVER) != 0)
|
||||||
|
{
|
||||||
|
Status = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((Data & I2C_REG_RAW_INTR_STAT_STOP_DET) != 0)
|
||||||
|
{
|
||||||
|
Status = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
vMicroSecondDelay(TI2C_POLL);
|
||||||
|
PollCount++;
|
||||||
|
if (PollCount >= MAX_STOP_DET_POLL_COUNT)
|
||||||
|
{
|
||||||
|
Status = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (TRUE);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
uint32_t WriteMultipleByte(uintn_t I2CAddress, uint8_t *WriteBuffer, uintn_t Length)
|
||||||
|
{
|
||||||
|
uintn_t I2CIoPortBaseAddress;
|
||||||
|
uintn_t Index;
|
||||||
|
uintn_t Addr;
|
||||||
|
uint32_t Data;
|
||||||
|
uint32_t Status = 0;
|
||||||
|
|
||||||
|
if (Length > I2C_FIFO_SIZE)
|
||||||
|
return -1; // Routine does not handle xfers > fifo size.
|
||||||
|
|
||||||
|
I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
|
||||||
|
|
||||||
|
// Write to the IC_TAR register the address of the slave device to be addressed
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_TAR;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
Data &= ~B_I2C_REG_TAR;
|
||||||
|
Data |= I2CAddress;
|
||||||
|
*((volatile uint32_t *) (uintn_t)(Addr)) = Data;
|
||||||
|
|
||||||
|
// Enable the I2C Controller
|
||||||
|
EnableI2CController ();
|
||||||
|
|
||||||
|
// Write the data and transfer direction to the IC_DATA_CMD register.
|
||||||
|
// Also specify that transfer should be terminated by STOP condition.
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
|
||||||
|
for (Index = 0; Index < Length; Index++)
|
||||||
|
{
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
Data &= 0xFFFFFF00;
|
||||||
|
Data |= (uint8_t)WriteBuffer[Index];
|
||||||
|
Data &= ~B_I2C_REG_DATA_CMD_RW;
|
||||||
|
if (Index == (Length-1))
|
||||||
|
Data |= B_I2C_REG_DATA_CMD_STOP;
|
||||||
|
*((volatile uint32_t *) (uintn_t)(Addr)) = Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for transfer completion
|
||||||
|
Status = WaitForStopDet ();
|
||||||
|
|
||||||
|
// Ensure I2C Controller disabled.
|
||||||
|
DisableI2CController ();
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void I2CWriteMultipleBytes(I2C_DEVICE_ADDRESS SlaveAddress,
|
||||||
|
I2C_ADDR_MODE AddrMode, uintn_t *Length, void *Buffer)
|
||||||
|
{
|
||||||
|
uintn_t I2CAddress;
|
||||||
|
uint16_t SaveCmd;
|
||||||
|
uint32_t SaveBar0;
|
||||||
|
|
||||||
|
if (Buffer != NULL && Length != NULL)
|
||||||
|
{
|
||||||
|
SaveCmd = 0;
|
||||||
|
SaveBar0 = 0;
|
||||||
|
I2cEntry (&SaveCmd, &SaveBar0);
|
||||||
|
if (InitializeInternal(AddrMode) == 0)
|
||||||
|
{
|
||||||
|
I2CAddress = SlaveAddress.I2CDeviceAddress;
|
||||||
|
WriteMultipleByte(I2CAddress, Buffer, (*Length));
|
||||||
|
}
|
||||||
|
I2cExit (SaveCmd, SaveBar0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
uint32_t ReadMultipleByte(uintn_t I2CAddress, uint8_t *Buffer,
|
||||||
|
uintn_t WriteLength, uintn_t ReadLength)
|
||||||
|
{
|
||||||
|
uintn_t I2CIoPortBaseAddress;
|
||||||
|
uintn_t Index;
|
||||||
|
uintn_t Addr;
|
||||||
|
uint32_t Data;
|
||||||
|
uint8_t PollCount;
|
||||||
|
uint32_t Status;
|
||||||
|
|
||||||
|
if (WriteLength > I2C_FIFO_SIZE || ReadLength > I2C_FIFO_SIZE)
|
||||||
|
return -1; // Routine does not handle xfers > fifo size.
|
||||||
|
|
||||||
|
I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
|
||||||
|
|
||||||
|
// Write to the IC_TAR register the address of the slave device to be addressed
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_TAR;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
Data &= ~B_I2C_REG_TAR;
|
||||||
|
Data |= I2CAddress;
|
||||||
|
*((volatile uint32_t *) (uintn_t)(Addr)) = Data;
|
||||||
|
|
||||||
|
// Enable the I2C Controller
|
||||||
|
EnableI2CController ();
|
||||||
|
|
||||||
|
// Write the data (sub-addresses) to the IC_DATA_CMD register.
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
|
||||||
|
for (Index = 0; Index < WriteLength; Index++)
|
||||||
|
{
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
Data &= 0xFFFFFF00;
|
||||||
|
Data |= (uint8_t)Buffer[Index];
|
||||||
|
Data &= ~B_I2C_REG_DATA_CMD_RW;
|
||||||
|
*((volatile uint32_t *) (uintn_t)(Addr)) = Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Issue Read Transfers for each byte (Restart issued when write/read bit changed).
|
||||||
|
for (Index = 0; Index < ReadLength; Index++)
|
||||||
|
{
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
Data |= B_I2C_REG_DATA_CMD_RW;
|
||||||
|
// Issue a STOP for last read transfer.
|
||||||
|
if (Index == (ReadLength-1))
|
||||||
|
Data |= B_I2C_REG_DATA_CMD_STOP;
|
||||||
|
*((volatile uint32_t *) (uintn_t)(Addr)) = Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for STOP condition.
|
||||||
|
Status = WaitForStopDet();
|
||||||
|
if (Status != 0)
|
||||||
|
{
|
||||||
|
// Poll Receive FIFO Buffer Level register until valid (upto MAX_T_POLL_COUNT times).
|
||||||
|
Data = 0;
|
||||||
|
PollCount = 0;
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_RXFLR;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
while ((Data != ReadLength) && (PollCount < MAX_T_POLL_COUNT))
|
||||||
|
{
|
||||||
|
vMicroSecondDelay(TI2C_POLL);
|
||||||
|
PollCount++;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
|
||||||
|
// If no timeout or device error then read rx data.
|
||||||
|
if (PollCount == MAX_T_POLL_COUNT)
|
||||||
|
{
|
||||||
|
Status = -1;
|
||||||
|
}
|
||||||
|
else if ((Data & I2C_REG_RAW_INTR_STAT_RX_OVER) != 0)
|
||||||
|
{
|
||||||
|
Status = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Clear RX underflow before reading IC_DATA_CMD.
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_CLR_RX_UNDER;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
|
||||||
|
// Read data.
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
|
||||||
|
for (Index = 0; Index < ReadLength; Index++)
|
||||||
|
{
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
Data &= 0x000000FF;
|
||||||
|
*(Buffer+Index) = (uint8_t)Data;
|
||||||
|
}
|
||||||
|
Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT;
|
||||||
|
Data = *((volatile uint32_t *) (uintn_t)(Addr));
|
||||||
|
Data &= I2C_REG_RAW_INTR_STAT_RX_UNDER;
|
||||||
|
if (Data != 0)
|
||||||
|
{
|
||||||
|
Status = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure I2C Controller disabled.
|
||||||
|
DisableI2CController ();
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void I2CReadMultipleBytes(I2C_DEVICE_ADDRESS SlaveAddress, I2C_ADDR_MODE AddrMode,
|
||||||
|
uintn_t *WriteLength, uintn_t *ReadLength, void *Buffer )
|
||||||
|
{
|
||||||
|
uintn_t I2CAddress;
|
||||||
|
uint16_t SaveCmd;
|
||||||
|
uint32_t SaveBar0;
|
||||||
|
|
||||||
|
if (Buffer != NULL && WriteLength != NULL && ReadLength != NULL)
|
||||||
|
{
|
||||||
|
SaveCmd = 0;
|
||||||
|
SaveBar0 = 0;
|
||||||
|
I2cEntry (&SaveCmd, &SaveBar0);
|
||||||
|
if (InitializeInternal(AddrMode) == 0)
|
||||||
|
{
|
||||||
|
I2CAddress = SlaveAddress.I2CDeviceAddress;
|
||||||
|
ReadMultipleByte(I2CAddress, Buffer, (*WriteLength), (*ReadLength));
|
||||||
|
}
|
||||||
|
I2cExit (SaveCmd, SaveBar0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Pcal9555 chips used on Galileo Gen 2 boards (see FAB-H schematic)
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static void Pcal9555SetPortRegBit(uint32_t Pcal9555SlaveAddr, uint32_t GpioNum, uint8_t RegBase, uint8_t LogicOne)
|
||||||
|
{
|
||||||
|
uintn_t ReadLength;
|
||||||
|
uintn_t WriteLength;
|
||||||
|
uint8_t Data[2];
|
||||||
|
uint8_t *RegValuePtr;
|
||||||
|
uint8_t GpioNumMask;
|
||||||
|
uint8_t SubAddr;
|
||||||
|
I2C_DEVICE_ADDRESS I2cDeviceAddr;
|
||||||
|
I2C_ADDR_MODE I2cAddrMode;
|
||||||
|
|
||||||
|
// Set I2C address and mode.
|
||||||
|
I2cDeviceAddr.I2CDeviceAddress = (uintn_t) Pcal9555SlaveAddr;
|
||||||
|
I2cAddrMode = EfiI2CSevenBitAddrMode;
|
||||||
|
|
||||||
|
// Set I2C subaddress and GPIO mask.
|
||||||
|
if (GpioNum < 8)
|
||||||
|
{
|
||||||
|
SubAddr = RegBase;
|
||||||
|
GpioNumMask = (uintn_t) (1 << GpioNum);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SubAddr = RegBase + 1;
|
||||||
|
GpioNumMask = (uintn_t) (1 << (GpioNum - 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output port value always at 2nd byte in Data variable.
|
||||||
|
RegValuePtr = &Data[1];
|
||||||
|
|
||||||
|
// On read entry - sub address at 2nd byte, on read exit - output
|
||||||
|
// port value in 2nd byte.
|
||||||
|
Data[1] = SubAddr;
|
||||||
|
WriteLength = 1;
|
||||||
|
ReadLength = 1;
|
||||||
|
I2CReadMultipleBytes(I2cDeviceAddr, I2cAddrMode, &WriteLength, &ReadLength, &Data[1]);
|
||||||
|
|
||||||
|
// Adjust output port bit using mask value.
|
||||||
|
if (LogicOne)
|
||||||
|
*RegValuePtr = *RegValuePtr | GpioNumMask;
|
||||||
|
else
|
||||||
|
*RegValuePtr = *RegValuePtr & ~(GpioNumMask);
|
||||||
|
|
||||||
|
// Update register. Sub address at 1st byte, value at 2nd byte.
|
||||||
|
WriteLength = 2;
|
||||||
|
Data[0] = SubAddr;
|
||||||
|
I2CWriteMultipleBytes(I2cDeviceAddr,I2cAddrMode, &WriteLength, Data);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void PlatformPcal9555GpioPullup(uint32_t Pcal9555SlaveAddr, uint32_t GpioNum, uint32_t Enable)
|
||||||
|
{
|
||||||
|
Pcal9555SetPortRegBit(Pcal9555SlaveAddr, GpioNum, PCAL9555_REG_PULL_EN_PORT0, Enable );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void PlatformPcal9555GpioSetDir(uint32_t Pcal9555SlaveAddr, uint32_t GpioNum, uint32_t CfgAsInput)
|
||||||
|
{
|
||||||
|
Pcal9555SetPortRegBit(Pcal9555SlaveAddr, GpioNum, PCAL9555_REG_CFG_PORT0, CfgAsInput);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void PlatformPcal9555GpioSetLevel(uint32_t Pcal9555SlaveAddr, uint32_t GpioNum, uint32_t HighLevel )
|
||||||
|
{
|
||||||
|
Pcal9555SetPortRegBit(Pcal9555SlaveAddr, GpioNum, PCAL9555_REG_OUT_PORT0, HighLevel );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* GPIO pin routing function
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static void vGalileoRouteLEDPins(void)
|
||||||
|
{
|
||||||
|
// For GpioNums below values 0 to 7 are for Port0 IE. P0-0 - P0-7 and
|
||||||
|
// values 8 to 15 are for Port1 IE. P1-0 - P1-7.
|
||||||
|
// Disable Pull-ups / pull downs on EXP0 pin for LVL_B_PU7 signal.
|
||||||
|
PlatformPcal9555GpioPullup (
|
||||||
|
GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
|
||||||
|
15, // P1-7.
|
||||||
|
FALSE
|
||||||
|
);
|
||||||
|
|
||||||
|
// Make LVL_B_OE7_N an output pin.
|
||||||
|
PlatformPcal9555GpioSetDir (
|
||||||
|
GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
|
||||||
|
14, // P1-6.
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
// Set level of LVL_B_OE7_N to low.
|
||||||
|
PlatformPcal9555GpioSetLevel (
|
||||||
|
GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR,
|
||||||
|
14,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
// Make MUX8_SEL an output pin.
|
||||||
|
PlatformPcal9555GpioSetDir (
|
||||||
|
GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1.
|
||||||
|
14, // P1-6.
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
// Set level of MUX8_SEL to low to route GPIO_SUS<5> to LED.
|
||||||
|
PlatformPcal9555GpioSetLevel (
|
||||||
|
GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1.
|
||||||
|
14, // P1-6.
|
||||||
|
FALSE);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
@ -0,0 +1,295 @@
|
|||||||
|
/*--------------------------------------------------------------------
|
||||||
|
Copyright(c) 2015 Intel Corporation. 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 Intel Corporation nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
--------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __GPIO_I2C_H__
|
||||||
|
#define __GPIO_I2C_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Any required includes
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#include "galileo_gen_defs.h"
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// PCI Configuration Map Register Offsets
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define PCI_REG_VID 0x00 // Vendor ID Register
|
||||||
|
#define PCI_REG_DID 0x02 // Device ID Register
|
||||||
|
#define PCI_REG_PCICMD 0x04 // PCI Command Register
|
||||||
|
#define PCI_REG_PCISTS 0x06 // PCI Status Register
|
||||||
|
#define PCI_REG_RID 0x08 // PCI Revision ID Register
|
||||||
|
#define PCI_REG_PI 0x09 // Programming Interface
|
||||||
|
#define PCI_REG_SCC 0x0a // Sub Class Code Register
|
||||||
|
#define PCI_REG_BCC 0x0b // Base Class Code Register
|
||||||
|
#define PCI_REG_PMLT 0x0d // Primary Master Latency Timer
|
||||||
|
#define PCI_REG_HDR 0x0e // Header Type Register
|
||||||
|
#define PCI_REG_PBUS 0x18 // Primary Bus Number Register
|
||||||
|
#define PCI_REG_SBUS 0x19 // Secondary Bus Number Register
|
||||||
|
#define PCI_REG_SUBUS 0x1a // Subordinate Bus Number Register
|
||||||
|
#define PCI_REG_SMLT 0x1b // Secondary Master Latency Timer
|
||||||
|
#define PCI_REG_IOBASE 0x1c // I/O base Register
|
||||||
|
#define PCI_REG_IOLIMIT 0x1d // I/O Limit Register
|
||||||
|
#define PCI_REG_SECSTATUS 0x1e // Secondary Status Register
|
||||||
|
#define PCI_REG_MEMBASE 0x20 // Memory Base Register
|
||||||
|
#define PCI_REG_MEMLIMIT 0x22 // Memory Limit Register
|
||||||
|
#define PCI_REG_PRE_MEMBASE 0x24 // Prefetchable memory Base register
|
||||||
|
#define PCI_REG_PRE_MEMLIMIT 0x26 // Prefetchable memory Limit register
|
||||||
|
#define PCI_REG_SVID0 0x2c // Subsystem Vendor ID low byte
|
||||||
|
#define PCI_REG_SVID1 0x2d // Subsystem Vendor ID high byte
|
||||||
|
#define PCI_REG_SID0 0x2e // Subsystem ID low byte
|
||||||
|
#define PCI_REG_SID1 0x2f // Subsystem ID high byte
|
||||||
|
#define PCI_REG_IOBASE_U 0x30 // I/O base Upper Register
|
||||||
|
#define PCI_REG_IOLIMIT_U 0x32 // I/O Limit Upper Register
|
||||||
|
#define PCI_REG_INTLINE 0x3c // Interrupt Line Register
|
||||||
|
#define PCI_REG_BRIDGE_CNTL 0x3e // Bridge Control Register
|
||||||
|
|
||||||
|
#define IO_PCI_ADDRESS(bus, dev, fn, reg) \
|
||||||
|
(0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// PCI Read/Write IO Data
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define IO_PCI_ADDRESS_PORT 0xcf8
|
||||||
|
#define IO_PCI_DATA_PORT 0xcfc
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// GPIO structures
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct __attribute__ ((__packed__)) BOARD_GPIO_CONTROLLER_CONFIG
|
||||||
|
{
|
||||||
|
uint32_t PortADR; ///< Value for IOH REG GPIO_SWPORTA_DR.
|
||||||
|
uint32_t PortADir; ///< Value for IOH REG GPIO_SWPORTA_DDR.
|
||||||
|
uint32_t IntEn; ///< Value for IOH REG GPIO_INTEN.
|
||||||
|
uint32_t IntMask; ///< Value for IOH REG GPIO_INTMASK.
|
||||||
|
uint32_t IntType; ///< Value for IOH REG GPIO_INTTYPE_LEVEL.
|
||||||
|
uint32_t IntPolarity; ///< Value for IOH REG GPIO_INT_POLARITY.
|
||||||
|
uint32_t Debounce; ///< Value for IOH REG GPIO_DEBOUNCE.
|
||||||
|
uint32_t LsSync; ///< Value for IOH REG GPIO_LS_SYNC.
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__ ((__packed__)) BOARD_LEGACY_GPIO_CONFIG
|
||||||
|
{
|
||||||
|
uint32_t CoreWellEnable; ///< Value for QNC NC Reg R_QNC_GPIO_CGEN_CORE_WELL.
|
||||||
|
uint32_t CoreWellIoSelect; ///< Value for QNC NC Reg R_QNC_GPIO_CGIO_CORE_WELL.
|
||||||
|
uint32_t CoreWellLvlForInputOrOutput; ///< Value for QNC NC Reg R_QNC_GPIO_CGLVL_CORE_WELL.
|
||||||
|
uint32_t CoreWellTriggerPositiveEdge; ///< Value for QNC NC Reg R_QNC_GPIO_CGTPE_CORE_WELL.
|
||||||
|
uint32_t CoreWellTriggerNegativeEdge; ///< Value for QNC NC Reg R_QNC_GPIO_CGTNE_CORE_WELL.
|
||||||
|
uint32_t CoreWellGPEEnable; ///< Value for QNC NC Reg R_QNC_GPIO_CGGPE_CORE_WELL.
|
||||||
|
uint32_t CoreWellSMIEnable; ///< Value for QNC NC Reg R_QNC_GPIO_CGSMI_CORE_WELL.
|
||||||
|
uint32_t CoreWellTriggerStatus; ///< Value for QNC NC Reg R_QNC_GPIO_CGTS_CORE_WELL.
|
||||||
|
uint32_t CoreWellNMIEnable; ///< Value for QNC NC Reg R_QNC_GPIO_CGNMIEN_CORE_WELL.
|
||||||
|
uint32_t ResumeWellEnable; ///< Value for QNC NC Reg R_QNC_GPIO_RGEN_RESUME_WELL.
|
||||||
|
uint32_t ResumeWellIoSelect; ///< Value for QNC NC Reg R_QNC_GPIO_RGIO_RESUME_WELL.
|
||||||
|
uint32_t ResumeWellLvlForInputOrOutput;///< Value for QNC NC Reg R_QNC_GPIO_RGLVL_RESUME_WELL.
|
||||||
|
uint32_t ResumeWellTriggerPositiveEdge;///< Value for QNC NC Reg R_QNC_GPIO_RGTPE_RESUME_WELL.
|
||||||
|
uint32_t ResumeWellTriggerNegativeEdge;///< Value for QNC NC Reg R_QNC_GPIO_RGTNE_RESUME_WELL.
|
||||||
|
uint32_t ResumeWellGPEEnable; ///< Value for QNC NC Reg R_QNC_GPIO_RGGPE_RESUME_WELL.
|
||||||
|
uint32_t ResumeWellSMIEnable; ///< Value for QNC NC Reg R_QNC_GPIO_RGSMI_RESUME_WELL.
|
||||||
|
uint32_t ResumeWellTriggerStatus; ///< Value for QNC NC Reg R_QNC_GPIO_RGTS_RESUME_WELL.
|
||||||
|
uint32_t ResumeWellNMIEnable; ///< Value for QNC NC Reg R_QNC_GPIO_RGNMIEN_RESUME_WELL.
|
||||||
|
} ;
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// GPIO definitions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define GALILEO_GEN2_GPIO_CONTROLLER_INITIALIZER {0x05, 0x05, 0, 0, 0, 0, 0, 0}
|
||||||
|
#define GALILEO_GEN2_LEGACY_GPIO_INITIALIZER {0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||||
|
0x03, 0x00, 0x3f, 0x1c, 0x02, 0x00, 0x00, \
|
||||||
|
0x00, 0x00, 0x3f, 0x00}
|
||||||
|
|
||||||
|
#define PLATFORM_GPIO_CONTROLLER_CONFIG_DEFINITION \
|
||||||
|
/* EFI_PLATFORM_TYPE - Galileo Gen 2 */ \
|
||||||
|
GALILEO_GEN2_GPIO_CONTROLLER_INITIALIZER ,\
|
||||||
|
|
||||||
|
#define PLATFORM_LEGACY_GPIO_CONFIG_DEFINITION \
|
||||||
|
/* EFI_PLATFORM_TYPE - Galileo Gen 2 */ \
|
||||||
|
GALILEO_GEN2_LEGACY_GPIO_INITIALIZER , \
|
||||||
|
|
||||||
|
#define IOH_I2C_GPIO_BUS_NUMBER 0x00
|
||||||
|
#define IOH_I2C_GPIO_DEVICE_NUMBER 0x15
|
||||||
|
#define IOH_I2C_GPIO_FUNCTION_NUMBER 0x02
|
||||||
|
|
||||||
|
#define INTEL_VENDOR_ID 0x8086
|
||||||
|
#define V_IOH_I2C_GPIO_VENDOR_ID INTEL_VENDOR_ID
|
||||||
|
#define V_IOH_I2C_GPIO_DEVICE_ID 0x0934
|
||||||
|
|
||||||
|
#define R_IOH_I2C_MEMBAR 0x10
|
||||||
|
#define R_IOH_GPIO_MEMBAR 0x14
|
||||||
|
|
||||||
|
#define GPIO_SWPORTA_DR 0x00
|
||||||
|
#define GPIO_SWPORTA_DDR 0x04
|
||||||
|
#define GPIO_SWPORTB_DR 0x0C
|
||||||
|
#define GPIO_SWPORTB_DDR 0x10
|
||||||
|
#define GPIO_SWPORTC_DR 0x18
|
||||||
|
#define GPIO_SWPORTC_DDR 0x1C
|
||||||
|
#define GPIO_SWPORTD_DR 0x24
|
||||||
|
#define GPIO_SWPORTD_DDR 0x28
|
||||||
|
#define GPIO_INTEN 0x30
|
||||||
|
#define GPIO_INTMASK 0x34
|
||||||
|
#define GPIO_INTTYPE_LEVEL 0x38
|
||||||
|
#define GPIO_INT_POLARITY 0x3C
|
||||||
|
#define GPIO_INTSTATUS 0x40
|
||||||
|
#define GPIO_RAW_INTSTATUS 0x44
|
||||||
|
#define GPIO_DEBOUNCE 0x48
|
||||||
|
#define GPIO_PORTA_EOI 0x4C
|
||||||
|
#define GPIO_EXT_PORTA 0x50
|
||||||
|
#define GPIO_EXT_PORTB 0x54
|
||||||
|
#define GPIO_EXT_PORTC 0x58
|
||||||
|
#define GPIO_EXT_PORTD 0x5C
|
||||||
|
#define GPIO_LS_SYNC 0x60
|
||||||
|
#define GPIO_CONFIG_REG2 0x70
|
||||||
|
#define GPIO_CONFIG_REG1 0x74
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// GPIO defines for cypress chip
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define PCAL9555_REG_OUT_PORT0 0x02
|
||||||
|
#define PCAL9555_REG_OUT_PORT1 0x03
|
||||||
|
#define PCAL9555_REG_CFG_PORT0 0x06
|
||||||
|
#define PCAL9555_REG_CFG_PORT1 0x07
|
||||||
|
#define PCAL9555_REG_PULL_EN_PORT0 0x46
|
||||||
|
#define PCAL9555_REG_PULL_EN_PORT1 0x47
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Three IO Expanders at fixed addresses on Galileo Gen2.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR 0x25
|
||||||
|
#define GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR 0x26
|
||||||
|
#define GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR 0x27
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Legacy GPIO defines
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define LEGACY_GPIO_BUS_NUMBER 0
|
||||||
|
#define LEGACY_GPIO_DEVICE_NUMBER 31
|
||||||
|
#define LEGACY_GPIO_FUNCTION_NUMBER 0
|
||||||
|
|
||||||
|
#define R_QNC_LPC_GBA_BASE 0x44
|
||||||
|
#define B_QNC_LPC_GPA_BASE_MASK 0x0000FFC0
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// I2C structures and enums
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/// The I2C hardware address to which the I2C device is preassigned or allocated.
|
||||||
|
uintn_t I2CDeviceAddress : 10;
|
||||||
|
} I2C_DEVICE_ADDRESS;
|
||||||
|
|
||||||
|
typedef enum _I2C_ADDR_MODE
|
||||||
|
{
|
||||||
|
EfiI2CSevenBitAddrMode,
|
||||||
|
EfiI2CTenBitAddrMode,
|
||||||
|
} I2C_ADDR_MODE;
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// I2C definitions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define GALILEO_GEN2_FLASH_UPDATE_LED_RESUMEWELL_GPIO 5
|
||||||
|
#define R_QNC_GPIO_CGEN_CORE_WELL 0x00
|
||||||
|
#define R_QNC_GPIO_CGIO_CORE_WELL 0x04
|
||||||
|
#define R_QNC_GPIO_CGLVL_CORE_WELL 0x08
|
||||||
|
#define R_QNC_GPIO_CGTPE_CORE_WELL 0x0C // Core well GPIO Trigger Positive Edge Enable
|
||||||
|
#define R_QNC_GPIO_CGTNE_CORE_WELL 0x10 // Core well GPIO Trigger Negative Edge Enable
|
||||||
|
#define R_QNC_GPIO_CGGPE_CORE_WELL 0x14 // Core well GPIO GPE Enable
|
||||||
|
#define R_QNC_GPIO_CGSMI_CORE_WELL 0x18 // Core well GPIO SMI Enable
|
||||||
|
#define R_QNC_GPIO_CGTS_CORE_WELL 0x1C // Core well GPIO Trigger Status
|
||||||
|
#define R_QNC_GPIO_RGEN_RESUME_WELL 0x20
|
||||||
|
#define R_QNC_GPIO_RGIO_RESUME_WELL 0x24
|
||||||
|
#define R_QNC_GPIO_RGLVL_RESUME_WELL 0x28
|
||||||
|
#define R_QNC_GPIO_RGTPE_RESUME_WELL 0x2C // Resume well GPIO Trigger Positive Edge Enable
|
||||||
|
#define R_QNC_GPIO_RGTNE_RESUME_WELL 0x30 // Resume well GPIO Trigger Negative Edge Enable
|
||||||
|
#define R_QNC_GPIO_RGGPE_RESUME_WELL 0x34 // Resume well GPIO GPE Enable
|
||||||
|
#define R_QNC_GPIO_RGSMI_RESUME_WELL 0x38 // Resume well GPIO SMI Enable
|
||||||
|
#define R_QNC_GPIO_RGTS_RESUME_WELL 0x3C // Resume well GPIO Trigger Status
|
||||||
|
#define R_QNC_GPIO_CNMIEN_CORE_WELL 0x40 // Core well GPIO NMI Enable
|
||||||
|
#define R_QNC_GPIO_RNMIEN_RESUME_WELL 0x44 // Resume well GPIO NMI Enable
|
||||||
|
|
||||||
|
#define B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK 0xFFFFF000 // [31:12].
|
||||||
|
#define I2C_REG_CLR_START_DET 0x64 // Clear START DET Interrupt Register
|
||||||
|
#define I2C_REG_CLR_STOP_DET 0x60 // Clear STOP DET Interrupt Register
|
||||||
|
#define B_I2C_REG_CLR_START_DET (BIT0) // Clear START DET Interrupt Register
|
||||||
|
#define B_I2C_REG_CLR_STOP_DET (BIT0) // Clear STOP DET Interrupt Register
|
||||||
|
#define B_I2C_REG_CON_10BITADD_MASTER (BIT4) // 7-bit addressing (0) or 10-bit addressing (1)
|
||||||
|
#define B_I2C_REG_CON_SPEED (BIT2+BIT1) // standard mode (01) or fast mode (10)
|
||||||
|
#define I2C_REG_CON 0x00 // Control Register
|
||||||
|
#define I2C_REG_ENABLE 0x6C // Enable Register
|
||||||
|
#define B_I2C_REG_ENABLE (BIT0) // Enable (1) or disable (0) I2C Controller
|
||||||
|
#define I2C_REG_ENABLE_STATUS 0x9C // Enable Status Register
|
||||||
|
#define I2C_REG_CLR_INT 0x40 // Clear Combined and Individual Interrupt Register
|
||||||
|
#define MAX_T_POLL_COUNT 100
|
||||||
|
#define TI2C_POLL 25 // microseconds
|
||||||
|
#define I2C_REG_CLR_RX_OVER 0x48 // Clear RX Over Interrupt Register
|
||||||
|
#define I2C_REG_CLR_TX_OVER 0x4C // Clear TX Over Interrupt Register
|
||||||
|
#define I2C_REG_CLR_TX_ABRT 0x54 // Clear TX ABRT Interrupt Register
|
||||||
|
#define I2C_FIFO_SIZE 16
|
||||||
|
#define I2C_REG_TAR 0x04 // Master Target Address Register
|
||||||
|
#define B_I2C_REG_TAR (BIT9+BIT8+BIT7+BIT6+BIT5+BIT4+BIT3+BIT2+BIT1+BIT0) // Master Target Address bits
|
||||||
|
#define I2C_REG_DATA_CMD 0x10 // Data Buffer and Command Register
|
||||||
|
#define B_I2C_REG_DATA_CMD_RW (BIT8) // Data Buffer and Command Register Read/Write bit
|
||||||
|
#define I2C_REG_RXFLR 0x78 // Receive FIFO Level Register
|
||||||
|
#define B_I2C_REG_DATA_CMD_STOP (BIT9) // Data Buffer and Command Register STOP bit
|
||||||
|
#define I2C_REG_RAW_INTR_STAT 0x34 // Raw Interrupt Status Register
|
||||||
|
#define I2C_REG_RAW_INTR_STAT_RX_OVER (BIT1) // Raw Interrupt Status Register RX Overflow signal status.
|
||||||
|
#define I2C_REG_RAW_INTR_STAT_RX_UNDER (BIT0) // Raw Interrupt Status Register RX Underflow signal status.
|
||||||
|
#define I2C_REG_CLR_RX_UNDER 0x44 // Clear RX Under Interrupt Register
|
||||||
|
#define MAX_STOP_DET_POLL_COUNT ((1000 * 1000) / TI2C_POLL) // Extreme for expected Stop detect.
|
||||||
|
#define I2C_REG_RAW_INTR_STAT_TX_ABRT (BIT6) // Raw Interrupt Status Register TX Abort status.
|
||||||
|
#define I2C_REG_RAW_INTR_STAT_TX_OVER (BIT3) // Raw Interrupt Status Register TX Overflow signal status.
|
||||||
|
#define I2C_REG_RAW_INTR_STAT_STOP_DET (BIT9) // Raw Interrupt Status Register STOP_DET signal status.
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// GPIO Prototypes
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define GPIO_OUTPUT (0)
|
||||||
|
#define GPIO_INPUT (1)
|
||||||
|
#define LOW (0)
|
||||||
|
#define HIGH (1)
|
||||||
|
#define GPIO_NUMBER (7UL)
|
||||||
|
|
||||||
|
void vMicroSecondDelay(uint32_t DelayTime);
|
||||||
|
void vMilliSecondDelay(uint32_t DelayTime);
|
||||||
|
void vGalileoInitializeLegacyGPIO(void);
|
||||||
|
void vGalileoInitializeGpioController(void);
|
||||||
|
void vGalileoLegacyGPIOInitializationForLED(void);
|
||||||
|
void vGalileoSetGPIOBitDirection(uint32_t GPIONumber, uint32_t Direction);
|
||||||
|
void vGalileoSetGPIOBitLevel(uint32_t GPIONumber, uint32_t Level);
|
||||||
|
void vGalileoBlinkLEDUsingLegacyGPIO(uint32_t Level);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern C */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __GPIO_I2C_H__ */
|
||||||
|
|
@ -0,0 +1,967 @@
|
|||||||
|
/*--------------------------------------------------------------------
|
||||||
|
Copyright(c) 2015 Intel Corporation. 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 Intel Corporation nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
--------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Any required includes
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "portmacro.h"
|
||||||
|
#include "galileo_support.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Function prototypes
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_0 == 1 )
|
||||||
|
static void vHPETIRQHandler0(void);
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_1 == 1 )
|
||||||
|
void vHPETIRQHandler1(void);
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_2 == 1 )
|
||||||
|
static void vHPETIRQHandler2(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Always inline HPET ISR related routines (even with no optimization),
|
||||||
|
* This is done for speed reasons to keep the ISR as fast as possible.
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
static inline void vSetTVS( uint32_t ) __attribute__((always_inline));
|
||||||
|
static inline void vSetHPETComparator( uint32_t, uint64_t ) __attribute__((always_inline));
|
||||||
|
static inline uint64_t ullReadHPETCounters( void ) __attribute__((always_inline));
|
||||||
|
static inline void vHPET_ISR (uint32_t) __attribute__((always_inline));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Global variables
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
volatile uint32_t hpet_general_status;
|
||||||
|
volatile uint32_t ulHPETTimerNumber [3] = {0, 1, 2};
|
||||||
|
volatile uint32_t ulHPETTotalInterrupts [3] = {0, 0, 0};
|
||||||
|
volatile uint32_t ulHPETElapsedSeconds [3] = {0, 0, 0};
|
||||||
|
volatile uint32_t ulHPETInterruptFrequency [3] = {0, 0, 0};
|
||||||
|
volatile uint32_t ulHPETTicksToInterrupt [3] = {0, 0, 0};
|
||||||
|
struct hpet_info PrintInfo[3] =
|
||||||
|
{
|
||||||
|
{0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{1, 0, 0, 0, 0, 0, 0},
|
||||||
|
{2, 0, 0, 0, 0, 0, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Static variables
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
static uint32_t hpet_general_id;
|
||||||
|
static uint32_t hpet_counter_tick_period;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* General HPET functions
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
static void vClearHPETCounters( void )
|
||||||
|
{
|
||||||
|
hpetHPET_MAIN_CTR_LOW = 0UL;
|
||||||
|
hpetHPET_MAIN_CTR_HIGH = 0UL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
void vClearHPETElapsedSeconds( void )
|
||||||
|
{
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_0 == 1 )
|
||||||
|
{
|
||||||
|
ulHPETElapsedSeconds[0] = 0UL;
|
||||||
|
ulHPETTotalInterrupts [0] = 0UL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_1 == 1 )
|
||||||
|
{
|
||||||
|
ulHPETElapsedSeconds[1] = 0UL;
|
||||||
|
ulHPETTotalInterrupts [1] = 0UL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_2 == 1 )
|
||||||
|
{
|
||||||
|
ulHPETElapsedSeconds[2] = 0UL;
|
||||||
|
ulHPETTotalInterrupts [2] = 0UL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
static inline void vSetTVS( uint32_t TimerNumber )
|
||||||
|
{
|
||||||
|
volatile uint32_t hpet_cfg = 0UL;
|
||||||
|
const uint32_t uiTVS = (1UL << 6UL);
|
||||||
|
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_0 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 0)
|
||||||
|
{
|
||||||
|
hpet_cfg = hpetHPET_TMR0_CONFIG_LOW | uiTVS;
|
||||||
|
hpetHPET_TMR0_CONFIG_LOW = hpet_cfg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_1 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 1)
|
||||||
|
{
|
||||||
|
hpet_cfg = hpetHPET_TMR1_CONFIG_LOW | uiTVS;
|
||||||
|
hpetHPET_TMR1_CONFIG_LOW = hpet_cfg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_2 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 2)
|
||||||
|
{
|
||||||
|
hpet_cfg = hpetHPET_TMR2_CONFIG_LOW | uiTVS;
|
||||||
|
hpetHPET_TMR2_CONFIG_LOW = hpet_cfg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
static inline void vSetHPETComparator( uint32_t TimerNumber, uint64_t Value )
|
||||||
|
{
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_0 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 0)
|
||||||
|
{
|
||||||
|
vSetTVS(TimerNumber);
|
||||||
|
hpetHPET_TMR0_COMPARATOR_LOW = (uint32_t)(Value & 0xFFFFFFFFULL);
|
||||||
|
vSetTVS(TimerNumber);
|
||||||
|
hpetHPET_TMR0_COMPARATOR_HIGH = (uint32_t)((Value >> 32UL) & 0xFFFFFFFFULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_1 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 1)
|
||||||
|
{
|
||||||
|
vSetTVS(TimerNumber);
|
||||||
|
hpetHPET_TMR1_COMPARATOR_LOW = (uint32_t)(Value & 0xFFFFFFFFULL);
|
||||||
|
vSetTVS(TimerNumber);
|
||||||
|
hpetHPET_TMR1_COMPARATOR_HIGH = (uint32_t)((Value >> 32UL) & 0xFFFFFFFFULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_2 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 2)
|
||||||
|
{
|
||||||
|
vSetTVS(TimerNumber);
|
||||||
|
hpetHPET_TMR2_COMPARATOR_LOW = (uint32_t)(Value & 0xFFFFFFFFULL);
|
||||||
|
vSetTVS(TimerNumber);
|
||||||
|
hpetHPET_TMR2_COMPARATOR_HIGH = (uint32_t)((Value >> 32UL) & 0xFFFFFFFFULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
static inline uint64_t ullReadHPETCounters( void )
|
||||||
|
{
|
||||||
|
volatile uint64_t Counters = (uint64_t)
|
||||||
|
(((uint64_t)hpetHPET_MAIN_CTR_HIGH << 32UL) |
|
||||||
|
(uint64_t)hpetHPET_MAIN_CTR_LOW);
|
||||||
|
return Counters;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
static void vStopHPETTimer( uint32_t ClearCounters )
|
||||||
|
{
|
||||||
|
uint32_t hpet_cfg = 0UL;
|
||||||
|
|
||||||
|
/* Clear configuration enable bit */
|
||||||
|
hpet_cfg = hpetHPET_GENERAL_CONFIGURATION;
|
||||||
|
hpet_cfg &= ~hpetHPET_CFG_ENABLE;
|
||||||
|
hpetHPET_GENERAL_CONFIGURATION = hpet_cfg;
|
||||||
|
|
||||||
|
/* Clear counters */
|
||||||
|
if (ClearCounters)
|
||||||
|
vClearHPETCounters();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
static void vStartHPETTimer( void )
|
||||||
|
{
|
||||||
|
uint32_t hpet_cfg = 0UL;
|
||||||
|
uint8_t LegacyMode = TRUE; // See table in doc # 329676 page 867
|
||||||
|
|
||||||
|
hpet_general_status = hpetHPET_GENERAL_STATUS;
|
||||||
|
|
||||||
|
if (hpet_general_status != 0x0UL)
|
||||||
|
hpetHPET_GENERAL_STATUS = hpet_general_status;
|
||||||
|
|
||||||
|
hpet_cfg = hpetHPET_GENERAL_CONFIGURATION;
|
||||||
|
hpet_cfg |= hpetHPET_CFG_ENABLE;
|
||||||
|
|
||||||
|
if(LegacyMode != FALSE)
|
||||||
|
hpet_cfg |= hpetHPET_CFG_LEGACY;
|
||||||
|
else
|
||||||
|
hpet_cfg &= ~hpetHPET_CFG_LEGACY;
|
||||||
|
|
||||||
|
hpetHPET_GENERAL_CONFIGURATION = hpet_cfg;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
static void vConfigureHPETTimer( uint32_t TimerNumber, uint32_t PeriodicMode )
|
||||||
|
{
|
||||||
|
uint32_t hpet_cfg = 0UL; // Configuration data
|
||||||
|
uint8_t IRQNumber = 0; // Hardware ISR number
|
||||||
|
uint8_t Triggering = 0; // Level or Edge sensitive
|
||||||
|
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_0 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 0)
|
||||||
|
{
|
||||||
|
IRQNumber = TIMER0_IRQ;
|
||||||
|
Triggering = TIMER0_TRIGGERING;
|
||||||
|
hpet_cfg = hpetHPET_TMR0_CONFIG_LOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_1 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 1)
|
||||||
|
{
|
||||||
|
IRQNumber = TIMER1_IRQ;
|
||||||
|
Triggering = TIMER1_TRIGGERING;
|
||||||
|
hpet_cfg = hpetHPET_TMR1_CONFIG_LOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_2 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 2)
|
||||||
|
{
|
||||||
|
IRQNumber = TIMER2_IRQ;
|
||||||
|
Triggering = TIMER2_TRIGGERING;
|
||||||
|
hpet_cfg = hpetHPET_TMR2_CONFIG_LOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Modify configuration */
|
||||||
|
if (PeriodicMode != FALSE)
|
||||||
|
{
|
||||||
|
hpet_cfg |= hpetHPET_TN_ENABLE | hpetHPET_TN_PERIODIC | hpetHPET_TN_SETVAL |
|
||||||
|
hpetHPET_TN_32BIT | ((IRQNumber & 0x1F) << 9UL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hpet_cfg |= hpetHPET_TN_ENABLE | hpetHPET_TN_SETVAL |
|
||||||
|
hpetHPET_TN_32BIT | ((IRQNumber & 0x1F) << 9UL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup triggering bit */
|
||||||
|
if (Triggering != hpetHPET_INT_EDGE)
|
||||||
|
hpet_cfg |= (1UL << 1UL);
|
||||||
|
else
|
||||||
|
hpet_cfg &= ~(1UL << 1UL);
|
||||||
|
|
||||||
|
/* write-out configuration */
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_0 == 1 )
|
||||||
|
if (TimerNumber == 0)
|
||||||
|
{
|
||||||
|
hpetHPET_TMR0_CONFIG_LOW = hpet_cfg;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_1 == 1 )
|
||||||
|
if (TimerNumber == 1)
|
||||||
|
{
|
||||||
|
hpetHPET_TMR1_CONFIG_LOW = hpet_cfg;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_2 == 1 )
|
||||||
|
if (TimerNumber == 2)
|
||||||
|
{
|
||||||
|
hpetHPET_TMR2_CONFIG_LOW = hpet_cfg;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
static void vGetHPETCapabilitiesAndStatus( void )
|
||||||
|
{
|
||||||
|
/* Get HPET capabilities and ID */
|
||||||
|
hpet_general_id = hpetHPET_GENERAL_ID;
|
||||||
|
|
||||||
|
/* Invalid vendor ID - Should be Intel (0x8086") */
|
||||||
|
if ((hpet_general_id >> 16) != 0x8086UL)
|
||||||
|
{
|
||||||
|
configASSERT( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get number of ns/tick - default is 69.841279 */
|
||||||
|
hpet_counter_tick_period = hpetHPET_COUNTER_TICK_PERIOD;
|
||||||
|
|
||||||
|
/* General status of HPET - bit 0 = T0, bit 1 = T1 and bit 2 = T2.
|
||||||
|
* In level triggered mode 1 means interrupt is active */
|
||||||
|
hpet_general_status = hpetHPET_GENERAL_STATUS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
static void vCheckHPETIRQCapabilities( uint32_t TimerNumber)
|
||||||
|
{
|
||||||
|
uint32_t hpet_cfg_h = 0UL;
|
||||||
|
uint32_t hpet_cfg_l = 0UL;
|
||||||
|
uint32_t IRQNumber = 0UL;
|
||||||
|
uint32_t Triggering = hpetHPET_INT_EDGE;
|
||||||
|
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_0 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 0)
|
||||||
|
{
|
||||||
|
IRQNumber = TIMER0_IRQ;
|
||||||
|
Triggering = TIMER0_TRIGGERING;
|
||||||
|
hpet_cfg_h = hpetHPET_TMR0_CONFIG_HIGH;
|
||||||
|
hpet_cfg_l = hpetHPET_TMR0_CONFIG_LOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_1 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 1)
|
||||||
|
{
|
||||||
|
IRQNumber = TIMER1_IRQ;
|
||||||
|
Triggering = TIMER1_TRIGGERING;
|
||||||
|
hpet_cfg_h = hpetHPET_TMR1_CONFIG_HIGH;
|
||||||
|
hpet_cfg_l = hpetHPET_TMR1_CONFIG_LOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_2 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 2)
|
||||||
|
{
|
||||||
|
IRQNumber = TIMER2_IRQ;
|
||||||
|
Triggering = TIMER2_TRIGGERING;
|
||||||
|
hpet_cfg_h = hpetHPET_TMR2_CONFIG_HIGH;
|
||||||
|
hpet_cfg_l = hpetHPET_TMR2_CONFIG_LOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Setup configuration register */
|
||||||
|
hpet_cfg_l |= hpetHPET_TN_ENABLE | hpetHPET_TN_PERIODIC |
|
||||||
|
hpetHPET_TN_32BIT | ((IRQNumber & 0x1F) << 9UL);
|
||||||
|
|
||||||
|
/* Setup triggering bit */
|
||||||
|
if (Triggering != hpetHPET_INT_EDGE)
|
||||||
|
hpet_cfg_l |= (1UL << 1UL);
|
||||||
|
else
|
||||||
|
hpet_cfg_l &= ~(1UL << 1UL);
|
||||||
|
|
||||||
|
/* Write then read back configuration */
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_0 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 0)
|
||||||
|
{
|
||||||
|
hpetHPET_TMR0_CONFIG_HIGH = hpet_cfg_h;
|
||||||
|
hpetHPET_TMR0_CONFIG_LOW = hpet_cfg_l;
|
||||||
|
hpet_cfg_l = hpetHPET_TMR0_CONFIG_LOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_1 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 1)
|
||||||
|
{
|
||||||
|
hpetHPET_TMR1_CONFIG_HIGH = hpet_cfg_h;
|
||||||
|
hpetHPET_TMR1_CONFIG_LOW = hpet_cfg_l;
|
||||||
|
hpet_cfg_l = hpetHPET_TMR1_CONFIG_LOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_2 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 2)
|
||||||
|
{
|
||||||
|
hpetHPET_TMR2_CONFIG_HIGH = hpet_cfg_h;
|
||||||
|
hpetHPET_TMR2_CONFIG_LOW = hpet_cfg_l;
|
||||||
|
hpet_cfg_l = hpetHPET_TMR2_CONFIG_LOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
static uint32_t uiCalibrateHPETTimer(uint32_t TimerNumber, uint32_t Calibrate)
|
||||||
|
{
|
||||||
|
uint32_t ticks_per_ms = 15422; // 1e-3/64.84127e-9 (denominator is hpet_counter_tick_period)
|
||||||
|
if (Calibrate)
|
||||||
|
{
|
||||||
|
uint32_t uiRunningTotal = 0UL;
|
||||||
|
uint32_t i = 0UL;
|
||||||
|
for (i = 0; i < 5; i++)
|
||||||
|
uiRunningTotal += uiCalibrateTimer(TimerNumber, hpetHPETIMER);
|
||||||
|
ticks_per_ms = (uiRunningTotal / 5);
|
||||||
|
}
|
||||||
|
return ticks_per_ms;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
static void vSetupIOApic( uint32_t TimerNumber )
|
||||||
|
{
|
||||||
|
uint8_t DeliveryMode = 1; // 0 means fixed (use ISR Vector)
|
||||||
|
uint8_t DestinationMode = 0; // Used by local APIC for MSI
|
||||||
|
uint8_t IRQPolarity = 1; // 0 means active high, 1 = active low
|
||||||
|
uint8_t InterruptMask = 0; // 0 means allow interrupts
|
||||||
|
uint8_t Triggering = hpetHPET_INT_EDGE; // Level or Edge sensitive
|
||||||
|
uint8_t IRQNumber = 0; // Hardware IRQ number
|
||||||
|
uint8_t ISRVector = 0; // Desired ISR vector
|
||||||
|
|
||||||
|
/* Select polarity and triggering */
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_0 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 0)
|
||||||
|
{
|
||||||
|
IRQNumber = TIMER0_IRQ;
|
||||||
|
ISRVector = hpetHPET_TIMER0_ISR_VECTOR;
|
||||||
|
IRQPolarity = TIMER0_POLARITY;
|
||||||
|
Triggering = TIMER0_TRIGGERING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_1 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 1)
|
||||||
|
{
|
||||||
|
IRQNumber = TIMER1_IRQ;
|
||||||
|
ISRVector = hpetHPET_TIMER1_ISR_VECTOR;
|
||||||
|
IRQPolarity = TIMER1_POLARITY;
|
||||||
|
Triggering = TIMER1_TRIGGERING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_2 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 2)
|
||||||
|
{
|
||||||
|
IRQNumber = TIMER2_IRQ;
|
||||||
|
ISRVector = hpetHPET_TIMER2_ISR_VECTOR;
|
||||||
|
IRQPolarity = TIMER2_POLARITY;
|
||||||
|
Triggering = TIMER2_TRIGGERING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Data to write to RTE register Lower DW */
|
||||||
|
uint32_t ConfigDataLDW = (uint32_t)(ISRVector | ((DeliveryMode & 0x07) << 8UL));
|
||||||
|
|
||||||
|
/* Set or clear bits in configuration data */
|
||||||
|
if (DestinationMode == 0)
|
||||||
|
ConfigDataLDW &= ~(1UL << 11UL);
|
||||||
|
else
|
||||||
|
ConfigDataLDW |= (1UL << 11UL);
|
||||||
|
|
||||||
|
if (IRQPolarity == 0)
|
||||||
|
ConfigDataLDW &= ~(1UL << 13UL);
|
||||||
|
else
|
||||||
|
ConfigDataLDW |= (1UL << 13UL);
|
||||||
|
|
||||||
|
if (Triggering != FALSE)
|
||||||
|
ConfigDataLDW |= (1UL << 15UL);
|
||||||
|
else
|
||||||
|
ConfigDataLDW &= ~(1UL << 15UL);
|
||||||
|
|
||||||
|
if (InterruptMask == 0)
|
||||||
|
ConfigDataLDW &= ~(1UL << 16UL);
|
||||||
|
else
|
||||||
|
ConfigDataLDW |= (1UL << 16UL);
|
||||||
|
|
||||||
|
/* Data to write to RTE register Upper DW */
|
||||||
|
uint32_t LocalAPIC_DID = ((portAPIC_ID_REGISTER & 0xFF000000UL) >> 24UL); // get local APIC DID
|
||||||
|
uint32_t LocalAPIC_EDID = ((portAPIC_ID_REGISTER & 0x00FF0000UL) >> 16UL); // get local APIC Extended DID
|
||||||
|
uint32_t ConfigDataUDW = (uint32_t)(((LocalAPIC_DID << 24UL) & 0xFF000000UL) |
|
||||||
|
((LocalAPIC_EDID << 16UL) & 0x00FF0000UL));
|
||||||
|
|
||||||
|
/* Setup IDX and WDW register to write RTE data */
|
||||||
|
hpetIO_APIC_IDX = hpetIO_APIC_RTE_OFFSET + ((2 * IRQNumber) + 1);
|
||||||
|
hpetIO_APIC_WDW = ConfigDataUDW;
|
||||||
|
hpetIO_APIC_IDX = hpetIO_APIC_RTE_OFFSET + ((2 * IRQNumber) + 0);
|
||||||
|
hpetIO_APIC_WDW = ConfigDataLDW;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
static void vInitilizeHPETInterrupt( uint32_t TimerNumber )
|
||||||
|
{
|
||||||
|
/* NOTE: In non-legacy mode interrupts are sent as MSI messages to LAPIC */
|
||||||
|
|
||||||
|
uint32_t ticks_per_ms = 0UL; // Get # ticks per ms
|
||||||
|
uint32_t InterruptFrequency = 0UL; // Get times per second to interrupt
|
||||||
|
|
||||||
|
/* Stop the timers and reset the main counter */
|
||||||
|
vStopHPETTimer(true);
|
||||||
|
|
||||||
|
/* Initialise hardware */
|
||||||
|
vSetupIOApic(TimerNumber);
|
||||||
|
|
||||||
|
/* Register ISRs. Purely for demonstration purposes, timer 0 and timer 2
|
||||||
|
use the central interrupt entry code, so are installed using
|
||||||
|
xPortRegisterCInterruptHandler(), while timer 1 uses its own interrupt
|
||||||
|
entry code, so is installed using xPortInstallInterruptHandler(). For
|
||||||
|
convenience the entry code for timer 1 is implemented at the bottom of
|
||||||
|
RegTest.S.See
|
||||||
|
http://www.freertos.org/RTOS_Intel_Quark_Galileo_GCC.html#interrupts for
|
||||||
|
more information. */
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_0 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 0)
|
||||||
|
{
|
||||||
|
InterruptFrequency = hpetHPET_TIMER0_INTERRUPT_RATE;
|
||||||
|
xPortRegisterCInterruptHandler( vHPETIRQHandler0, hpetHPET_TIMER0_ISR_VECTOR );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_1 == 1 )
|
||||||
|
{
|
||||||
|
if (TimerNumber == 1)
|
||||||
|
{
|
||||||
|
extern void vApplicationHPETTimer1Wrapper( void );
|
||||||
|
|
||||||
|
InterruptFrequency = hpetHPET_TIMER1_INTERRUPT_RATE;
|
||||||
|
xPortInstallInterruptHandler( vApplicationHPETTimer1Wrapper, hpetHPET_TIMER1_ISR_VECTOR );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if ( hpetUSE_HPET_TIMER_NUMBER_2 == 1)
|
||||||
|
{
|
||||||
|
if (TimerNumber == 2)
|
||||||
|
{
|
||||||
|
configASSERT(TimerNumber == 2)
|
||||||
|
InterruptFrequency = hpetHPET_TIMER2_INTERRUPT_RATE;
|
||||||
|
xPortRegisterCInterruptHandler( vHPETIRQHandler2, hpetHPET_TIMER2_ISR_VECTOR );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get calibrated ticks per millisecond before initialization. */
|
||||||
|
ticks_per_ms = uiCalibrateHPETTimer(TimerNumber, TRUE);
|
||||||
|
|
||||||
|
/* Check IRQ compatibility - will assert here if there is a problem. */
|
||||||
|
vCheckHPETIRQCapabilities(TimerNumber);
|
||||||
|
|
||||||
|
/* Get HPET capabilities and ID and status */
|
||||||
|
vGetHPETCapabilitiesAndStatus();
|
||||||
|
|
||||||
|
/* Sanity check for frequency */
|
||||||
|
if ( InterruptFrequency < 1 )
|
||||||
|
InterruptFrequency = 20; // default is 50 ms interrupt rate
|
||||||
|
|
||||||
|
/* Save interrupt frequency */
|
||||||
|
ulHPETInterruptFrequency[TimerNumber] = InterruptFrequency;
|
||||||
|
|
||||||
|
/* Calculate required number of ticks */
|
||||||
|
uint32_t ticks = ( ticks_per_ms * 1000UL ) / ulHPETInterruptFrequency[TimerNumber];
|
||||||
|
|
||||||
|
/* Save the number of ticks to interrupt */
|
||||||
|
ulHPETTicksToInterrupt[TimerNumber] = ticks;
|
||||||
|
|
||||||
|
/* Make sure counters are zeroed */
|
||||||
|
vClearHPETCounters();
|
||||||
|
|
||||||
|
/* Write out comparator value */
|
||||||
|
vSetHPETComparator(TimerNumber, ticks);
|
||||||
|
|
||||||
|
/* Set target timer non-periodic mode with first interrupt at tick */
|
||||||
|
vConfigureHPETTimer(TimerNumber, FALSE);
|
||||||
|
|
||||||
|
/* Start the timer */
|
||||||
|
vStartHPETTimer();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
void vInitializeAllHPETInterrupts( void )
|
||||||
|
{
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_0 == 1 )
|
||||||
|
vInitilizeHPETInterrupt( 0 );
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_1 == 1 )
|
||||||
|
vInitilizeHPETInterrupt( 1 );
|
||||||
|
#endif
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_2 == 1 )
|
||||||
|
vInitilizeHPETInterrupt( 2 );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
uint32_t uiCalibrateTimer( uint32_t TimerNumber, uint32_t TimerType)
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
/* NOTE: If TimerType = LVTIMER then TimerNumber is ignored (PIT # 2 */
|
||||||
|
/* is always used) */
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
/* PIT (programmable interval timer) mode register Bit definitions */
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Mode register is at address 0x43:
|
||||||
|
Bits Usage
|
||||||
|
6 and 7 Select channel :
|
||||||
|
0 0 = Channel 0
|
||||||
|
0 1 = Channel 1
|
||||||
|
1 0 = Channel 2
|
||||||
|
1 1 = Read-back command (8254 only)
|
||||||
|
4 and 5 Access mode :
|
||||||
|
0 0 = Latch count value command
|
||||||
|
0 1 = Access mode: lobyte only
|
||||||
|
1 0 = Access mode: hibyte only
|
||||||
|
1 1 = Access mode: lobyte/hibyte
|
||||||
|
1 to 3 Operating mode :
|
||||||
|
0 0 0 = Mode 0 (interrupt on terminal count)
|
||||||
|
0 0 1 = Mode 1 (hardware re-triggerable one-shot)
|
||||||
|
0 1 0 = Mode 2 (rate generator)
|
||||||
|
0 1 1 = Mode 3 (square wave generator)
|
||||||
|
1 0 0 = Mode 4 (software triggered strobe)
|
||||||
|
1 0 1 = Mode 5 (hardware triggered strobe)
|
||||||
|
1 1 0 = Mode 2 (rate generator, same as 010b)
|
||||||
|
1 1 1 = Mode 3 (square wave generator, same as 011b)
|
||||||
|
0 BCD/Binary mode: 0 = 16-bit binary, 1 = four-digit BCD
|
||||||
|
----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Used to calculate LVT ticks */
|
||||||
|
const uint32_t uiLargeNumber = 0x7fffffffUL;
|
||||||
|
|
||||||
|
/* Default return value */
|
||||||
|
uint32_t ticks = 0;
|
||||||
|
|
||||||
|
/* Check timer type */
|
||||||
|
switch (TimerType)
|
||||||
|
{
|
||||||
|
case hpetLVTIMER:
|
||||||
|
case hpetHPETIMER:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ticks;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set timeout counter to a very large value */
|
||||||
|
uint64_t timeout_counter = (uint64_t) (uiLargeNumber * 4);
|
||||||
|
|
||||||
|
/* Set PIT Ch2 to one-shot mode */
|
||||||
|
uint32_t gate_register = ((inw(GATE_CONTROL) & 0xfd) | 0x01);
|
||||||
|
outw(GATE_CONTROL, gate_register);
|
||||||
|
outw(MODE_REGISTER, ONESHOT_MODE);
|
||||||
|
|
||||||
|
/* Set counter for 10 ms - 1193180/100 Hz ~ 11932 */
|
||||||
|
uint16_t pit_counter = 11932;
|
||||||
|
outb(CHANNEL2_DATA, (char) (pit_counter & 0xff));
|
||||||
|
outb(CHANNEL2_DATA, (char) ((pit_counter >> 8) & 0xff));
|
||||||
|
|
||||||
|
/* Start target timer */
|
||||||
|
if (TimerType == hpetLVTIMER)
|
||||||
|
{
|
||||||
|
portAPIC_LVT_TIMER = portAPIC_TIMER_INT_VECTOR;
|
||||||
|
portAPIC_TMRDIV = portAPIC_DIV_16;
|
||||||
|
}
|
||||||
|
else if (TimerType == hpetHPETIMER)
|
||||||
|
{
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
// Initialize HPE timer
|
||||||
|
vStopHPETTimer(TRUE);
|
||||||
|
/* Write out comparator value - we don't want it to interrupt */
|
||||||
|
vSetHPETComparator(TimerNumber, 0xFFFFFFFFUL);
|
||||||
|
// Configure HPE timer for non-periodic mode
|
||||||
|
vConfigureHPETTimer(TimerNumber, FALSE);
|
||||||
|
#else
|
||||||
|
( void ) TimerNumber;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset PIT one-shot counter */
|
||||||
|
gate_register = (inw(GATE_CONTROL) & 0xfe);
|
||||||
|
outw(GATE_CONTROL, gate_register);
|
||||||
|
gate_register |= 0x01;
|
||||||
|
outw(GATE_CONTROL, gate_register);
|
||||||
|
|
||||||
|
/* Setup target timer initial counts */
|
||||||
|
if (TimerType == hpetLVTIMER)
|
||||||
|
{
|
||||||
|
portAPIC_TIMER_INITIAL_COUNT = uiLargeNumber;
|
||||||
|
}
|
||||||
|
else if (TimerType == hpetHPETIMER)
|
||||||
|
{
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
vStartHPETTimer();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for PIT counter to expire */
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
gate_register = inw(GATE_CONTROL);
|
||||||
|
if ((gate_register & 0x20) || (--timeout_counter == 0))
|
||||||
|
{
|
||||||
|
/* Stop target timer and exit loop */
|
||||||
|
if (TimerType == hpetLVTIMER)
|
||||||
|
{
|
||||||
|
portAPIC_LVT_TIMER = portAPIC_DISABLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (TimerType == hpetHPETIMER)
|
||||||
|
{
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
vStopHPETTimer(FALSE);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for timeout */
|
||||||
|
if (timeout_counter != 0)
|
||||||
|
{
|
||||||
|
if (TimerType == hpetLVTIMER)
|
||||||
|
{
|
||||||
|
/* Counter started at a large number so subtract counts */
|
||||||
|
ticks = (uiLargeNumber - portAPIC_TIMER_CURRENT_COUNT);
|
||||||
|
/* adjust ticks for 1 ms and divider ratio */
|
||||||
|
ticks = ((((ticks << 4UL) * 100) / 1000) >> 4UL);
|
||||||
|
}
|
||||||
|
else if (TimerType == hpetHPETIMER)
|
||||||
|
{
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
/* Read timer counter - we only need the low counter */
|
||||||
|
ticks = (uint32_t)(ullReadHPETCounters() & 0xFFFFFFFFULL);
|
||||||
|
/* Clear timer counter */
|
||||||
|
vClearHPETCounters();
|
||||||
|
/* Return 1 ms tick counts. Timed for 10 ms so just divide by 10 */
|
||||||
|
ticks /= 10;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return adjusted counts for a 1 ms interrupt rate.
|
||||||
|
* Should be approximately 25000 for LV Timer.
|
||||||
|
* Should be approximately 15000 for HPE Timers */
|
||||||
|
return ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Interrupt service functions
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
static inline void vHPET_ISR( uint32_t TimerNumber )
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
/* Notes: In edge triggered mode, no need to clear int status bits.*/
|
||||||
|
/* */
|
||||||
|
/* In non-periodic mode, comparator is added to current counts, */
|
||||||
|
/* do not clear main counters. */
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
__asm volatile( "cli" );
|
||||||
|
|
||||||
|
/* Bump HPE timer interrupt count - available in a global variable */
|
||||||
|
ulHPETTotalInterrupts[TimerNumber] += 1UL;
|
||||||
|
|
||||||
|
/* Bump HPE timer elapsed seconds count - available in a global variable */
|
||||||
|
if ((ulHPETTotalInterrupts[TimerNumber] %
|
||||||
|
(ulHPETInterruptFrequency[TimerNumber] + 0UL)) == 0UL)
|
||||||
|
ulHPETElapsedSeconds[TimerNumber] += 1UL;
|
||||||
|
|
||||||
|
/* Reload comparators - a must do in non-periodic mode */
|
||||||
|
uint64_t ullNewValue = (uint64_t)
|
||||||
|
(ullReadHPETCounters() + (uint64_t)ulHPETTicksToInterrupt[TimerNumber]);
|
||||||
|
vSetHPETComparator(TimerNumber, ullNewValue);
|
||||||
|
|
||||||
|
__asm volatile( "sti" );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_0 == 1 )
|
||||||
|
extern void vApplicationHPETTimer0Handler( void );
|
||||||
|
static void vHPETIRQHandler0( void )
|
||||||
|
{
|
||||||
|
vHPET_ISR( 0 );
|
||||||
|
vApplicationHPETTimer0Handler();
|
||||||
|
hpetIO_APIC_EOI = hpetHPET_TIMER0_ISR_VECTOR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_1 == 1 )
|
||||||
|
extern void vApplicationHPETTimer1Handler( void );
|
||||||
|
void vHPETIRQHandler1( void )
|
||||||
|
{
|
||||||
|
vHPET_ISR( 1 );
|
||||||
|
vApplicationHPETTimer1Handler();
|
||||||
|
hpetIO_APIC_EOI = hpetHPET_TIMER1_ISR_VECTOR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( hpetUSE_HPET_TIMER_NUMBER_2 == 1 )
|
||||||
|
extern void vApplicationHPETTimer2Handler( void );
|
||||||
|
static void vHPETIRQHandler2( void )
|
||||||
|
{
|
||||||
|
vHPET_ISR( 2 );
|
||||||
|
vApplicationHPETTimer2Handler();
|
||||||
|
hpetIO_APIC_EOI = hpetHPET_TIMER2_ISR_VECTOR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Print HPET information functions
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#if ((hpetHPET_PRINT_INFO == 1 ) && (hpetHPET_TIMER_IN_USE))
|
||||||
|
static void prvUpdateHPETInfoTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
TickType_t xNextWakeTime, xBlockTime;
|
||||||
|
uint32_t TimerNumber;
|
||||||
|
uint8_t row, col, execute;
|
||||||
|
struct hpet_info *pi;
|
||||||
|
|
||||||
|
/* Remove compiler warning about unused parameter. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Initialise xNextWakeTime - this only needs to be done once. */
|
||||||
|
xNextWakeTime = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* Set task blocking period. */
|
||||||
|
xBlockTime = pdMS_TO_TICKS( 500 );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Place this task in the blocked state until it is time to run again. */
|
||||||
|
vTaskDelayUntil( &xNextWakeTime, xBlockTime );
|
||||||
|
|
||||||
|
/* Print all information */
|
||||||
|
for (TimerNumber = 0; TimerNumber <= 2; TimerNumber++)
|
||||||
|
{
|
||||||
|
execute = pdFALSE;
|
||||||
|
pi = &PrintInfo[TimerNumber];
|
||||||
|
pi->timer_number = TimerNumber;
|
||||||
|
pi->main_counter_h = hpetHPET_MAIN_CTR_HIGH;
|
||||||
|
pi->main_counter_l = hpetHPET_MAIN_CTR_LOW;
|
||||||
|
pi->total_interrupts = ulHPETTotalInterrupts[TimerNumber];
|
||||||
|
pi->elapsed_seconds = ulHPETElapsedSeconds[TimerNumber];
|
||||||
|
#if (hpetUSE_HPET_TIMER_NUMBER_0 == 1 )
|
||||||
|
if(TimerNumber == 0)
|
||||||
|
{
|
||||||
|
row = 8 ; col = 1;
|
||||||
|
pi->comparator_h = hpetHPET_TMR0_COMPARATOR_HIGH;
|
||||||
|
pi->comparator_l = hpetHPET_TMR0_COMPARATOR_LOW;
|
||||||
|
execute = pdTRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if ( hpetUSE_HPET_TIMER_NUMBER_1 == 1 )
|
||||||
|
if(TimerNumber == 1)
|
||||||
|
{
|
||||||
|
row = 12 ; col = 1;
|
||||||
|
pi->comparator_h = hpetHPET_TMR1_COMPARATOR_HIGH;
|
||||||
|
pi->comparator_l = hpetHPET_TMR1_COMPARATOR_LOW;
|
||||||
|
execute = pdTRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if ( hpetUSE_HPET_TIMER_NUMBER_2 == 1 )
|
||||||
|
if(TimerNumber == 2)
|
||||||
|
{
|
||||||
|
row = 16 ; col = 1;
|
||||||
|
pi->comparator_h = hpetHPET_TMR2_COMPARATOR_HIGH;
|
||||||
|
pi->comparator_l = hpetHPET_TMR2_COMPARATOR_LOW;
|
||||||
|
execute = pdTRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Print information on screen */
|
||||||
|
if(execute == pdTRUE)
|
||||||
|
{
|
||||||
|
g_printf_rcc(row, col, ANSI_COLOR_WHITE,
|
||||||
|
" HPE Timer Number = %d", pi->timer_number);
|
||||||
|
g_printf_rcc(row+1, col, ANSI_COLOR_WHITE,
|
||||||
|
" Timer Counters = 0x%08x:%08x, Comparator = 0x%08x:%08x",
|
||||||
|
pi->main_counter_h, pi->main_counter_l,
|
||||||
|
pi->comparator_h, pi->comparator_l);
|
||||||
|
g_printf_rcc(row+2, col, ANSI_COLOR_WHITE,
|
||||||
|
" Total Interrupts = 0x%08x Elapsed Seconds = %u",
|
||||||
|
pi->total_interrupts, pi->elapsed_seconds);
|
||||||
|
g_printf_rcc(row+3, col, DEFAULT_SCREEN_COLOR , "\r");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vCreateHPETInfoUpdateTask( void )
|
||||||
|
{
|
||||||
|
#if ((hpetHPET_PRINT_INFO == 1 ) && (hpetHPET_TIMER_IN_USE))
|
||||||
|
/* Create the task that displays HPE timer information. */
|
||||||
|
xTaskCreate( prvUpdateHPETInfoTask, "HPETInfo", (configMINIMAL_STACK_SIZE << 1),
|
||||||
|
NULL, (tskIDLE_PRIORITY), NULL );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,174 @@
|
|||||||
|
/*--------------------------------------------------------------------
|
||||||
|
Copyright(c) 2015 Intel Corporation. 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 Intel Corporation nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
--------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef HPET_H
|
||||||
|
#define HPET_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// HPET support definitions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define hpetUSE_HPET_TIMER_NUMBER_0 ( 1 ) // 0 = false, 1 = true
|
||||||
|
#define hpetUSE_HPET_TIMER_NUMBER_1 ( 1 ) // 0 = false, 1 = true
|
||||||
|
#define hpetUSE_HPET_TIMER_NUMBER_2 ( 1 ) // 0 = false, 1 = true
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// HPE timers general purpose register addresses
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define hpetHPET_GENERAL_ID ( *( ( volatile uint32_t * ) 0xFED00000UL ) )
|
||||||
|
#define hpetHPET_COUNTER_TICK_PERIOD ( *( ( volatile uint32_t * ) 0xFED00004UL ) )
|
||||||
|
#define hpetHPET_GENERAL_CONFIGURATION ( *( ( volatile uint32_t * ) 0xFED00010UL ) )
|
||||||
|
#define hpetHPET_GENERAL_STATUS ( *( ( volatile uint32_t * ) 0xFED00020UL ) )
|
||||||
|
#define hpetHPET_MAIN_CTR_LOW ( *( ( volatile uint32_t * ) 0xFED000F0UL ) )
|
||||||
|
#define hpetHPET_MAIN_CTR_HIGH ( *( ( volatile uint32_t * ) 0xFED000F4UL ) )
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// HPE timer specific support definitions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#if (hpetUSE_HPET_TIMER_NUMBER_0 == 1)
|
||||||
|
#define TIMER0_TRIGGERING ( 0 ) // 1 = level, 0 = edge
|
||||||
|
#define TIMER0_POLARITY ( 0 ) // 0 = active high, 1 = active low
|
||||||
|
#define TIMER0_IRQ ( 2 ) // 0 is default for legacy 8259, 2 for IO APIC
|
||||||
|
#define hpetHPET_TIMER0_ISR_VECTOR ( 0x32 ) // HPET Timer - I/O APIC
|
||||||
|
#define hpetHPET_TIMER0_INTERRUPT_RATE ( 2000 ) // Number of times per second to interrupt
|
||||||
|
#define hpetHPET_TMR0_CONFIG_LOW ( *( ( volatile uint32_t * ) 0xFED00100UL ) )
|
||||||
|
#define hpetHPET_TMR0_CONFIG_HIGH ( *( ( volatile uint32_t * ) 0xFED00104UL ) )
|
||||||
|
#define hpetHPET_TMR0_COMPARATOR_LOW ( *( ( volatile uint32_t * ) 0xFED00108UL ) )
|
||||||
|
#define hpetHPET_TMR0_COMPARATOR_HIGH ( *( ( volatile uint32_t * ) 0xFED0010CUL ) )
|
||||||
|
#endif
|
||||||
|
#if (hpetUSE_HPET_TIMER_NUMBER_1 == 1)
|
||||||
|
#define TIMER1_TRIGGERING ( 0 ) // 1 = level, 0 = edge
|
||||||
|
#define TIMER1_POLARITY ( 0 ) // 0 = active high, 1 = active low
|
||||||
|
#define TIMER1_IRQ ( 8 ) // 8 is default for 8259 & IO APIC
|
||||||
|
#define hpetHPET_TIMER1_ISR_VECTOR ( 0x85 ) // HPET Timer - I/O APIC
|
||||||
|
#define hpetHPET_TIMER1_INTERRUPT_RATE ( 1500 ) // Number of times per second to interrupt
|
||||||
|
#define hpetHPET_TMR1_CONFIG_LOW ( *( ( volatile uint32_t * ) 0xFED00120UL ) )
|
||||||
|
#define hpetHPET_TMR1_CONFIG_HIGH ( *( ( volatile uint32_t * ) 0xFED00124UL ) )
|
||||||
|
#define hpetHPET_TMR1_COMPARATOR_LOW ( *( ( volatile uint32_t * ) 0xFED00128UL ) )
|
||||||
|
#define hpetHPET_TMR1_COMPARATOR_HIGH ( *( ( volatile uint32_t * ) 0xFED0012CUL ) )
|
||||||
|
#endif
|
||||||
|
#if (hpetUSE_HPET_TIMER_NUMBER_2 == 1)
|
||||||
|
#define TIMER2_TRIGGERING ( 0 ) // 1 = level, 0 = edge
|
||||||
|
#define TIMER2_POLARITY ( 0 ) // 0 = active high, 1 = active low
|
||||||
|
#define TIMER2_IRQ ( 11 ) // 11 is default for 8259 & IO APIC
|
||||||
|
#define hpetHPET_TIMER2_ISR_VECTOR ( 0x95 ) // HPET Timer - I/O APIC
|
||||||
|
#define hpetHPET_TIMER2_INTERRUPT_RATE ( 1400 ) // Number of times per second to interrupt
|
||||||
|
#define hpetHPET_TMR2_CONFIG_LOW ( *( ( volatile uint32_t * ) 0xFED00140UL ) )
|
||||||
|
#define hpetHPET_TMR2_CONFIG_HIGH ( *( ( volatile uint32_t * ) 0xFED00144UL ) )
|
||||||
|
#define hpetHPET_TMR2_COMPARATOR_LOW ( *( ( volatile uint32_t * ) 0xFED00148UL ) )
|
||||||
|
#define hpetHPET_TMR2_COMPARATOR_HIGH ( *( ( volatile uint32_t * ) 0xFED0014CUL ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Disables code if no timer is enabled (quiets the compiler)
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define hpetHPET_TIMER_IN_USE (hpetUSE_HPET_TIMER_NUMBER_0 | hpetUSE_HPET_TIMER_NUMBER_1 | hpetUSE_HPET_TIMER_NUMBER_2)
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Allow HPET variable printout on screen (1 = allow)
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define hpetHPET_PRINT_INFO 0
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// HPET bit checking and manipulation definitions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define hpetHPET_CFG_ENABLE 0x001
|
||||||
|
#define hpetHPET_CFG_LEGACY 0x002
|
||||||
|
#define hpetHPET_TN_ENABLE 0x004
|
||||||
|
#define hpetHPET_TN_PERIODIC 0x008
|
||||||
|
#define hpetHPET_TN_PERIODIC_CAP 0x010
|
||||||
|
#define hpetHPET_TN_SETVAL 0x040
|
||||||
|
#define hpetHPET_TN_32BIT 0x100
|
||||||
|
#define hpetHPET_INT_EDGE 0x000
|
||||||
|
#define hpetHPET_INT_LEVEL 0x001
|
||||||
|
#define hpetHPET_POL_HIGH 0x000
|
||||||
|
#define hpetHPET_POL_LOW 0x001
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// I/O APIC register addresses and definitions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define hpetIO_APIC_IDX ( *( ( volatile uint32_t * ) 0xFEC00000UL ) )
|
||||||
|
#define hpetIO_APIC_WDW ( *( ( volatile uint32_t * ) 0xFEC00010UL ) )
|
||||||
|
#define hpetIO_APIC_EOI ( *( ( volatile uint32_t * ) 0xFEC00040UL ) )
|
||||||
|
|
||||||
|
#define hpetIO_APIC_ID 0x00 // Get/Set APIC ID information
|
||||||
|
#define hpetIO_APIC_VERSION 0x01 // Get APIC version information
|
||||||
|
#define hpetIO_APIC_RTE_OFFSET 0x10 // add 2* RTE Table (0-23) to this offset
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Used for timer calibration
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define hpetLVTIMER ( 0 ) // Constant definition
|
||||||
|
#define hpetHPETIMER ( 1 ) // Constant definition
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// HPET variables Structure
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
struct __attribute__ ((__packed__)) hpet_info
|
||||||
|
{
|
||||||
|
unsigned int timer_number;
|
||||||
|
unsigned int main_counter_h;
|
||||||
|
unsigned int main_counter_l;
|
||||||
|
unsigned int comparator_h;
|
||||||
|
unsigned int comparator_l;
|
||||||
|
unsigned int total_interrupts;
|
||||||
|
unsigned int elapsed_seconds;
|
||||||
|
};
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Variables other modules may want to access
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
extern volatile uint32_t hpet_general_status;
|
||||||
|
extern volatile uint32_t ulHPETTimerNumber [3];
|
||||||
|
extern volatile uint32_t ulHPETTotalInterrupts [3];
|
||||||
|
extern volatile uint32_t ulHPETElapsedSeconds [3];
|
||||||
|
extern volatile uint32_t ulHPETInterruptFrequency [3];
|
||||||
|
extern volatile uint32_t ulHPETTicksToInterrupt [3];
|
||||||
|
extern struct hpet_info PrintInfo[3];
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Function prototypes
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#if (hpetHPET_TIMER_IN_USE)
|
||||||
|
void vClearHPETElapsedSeconds( void );
|
||||||
|
uint32_t uiCalibrateTimer(uint32_t TimerNumber, uint32_t TimerType );
|
||||||
|
void vInitializeAllHPETInterrupts( void );
|
||||||
|
void vCreateHPETInfoUpdateTask( void );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern C */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HPET_H */
|
||||||
|
|
@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The library functions not provided by libgcc for freestanding environments.
|
||||||
|
* The implementation of the functions in this file have made NO attempt
|
||||||
|
* whatsoever to be optimised!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#warning The functions in this file are very basic, and not optimised.
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void *memcpy( void *pvDest, const void *pvSource, size_t xBytes )
|
||||||
|
{
|
||||||
|
/* The compiler used during development seems to err unless these volatiles are
|
||||||
|
included at -O3 optimisation. */
|
||||||
|
volatile unsigned char *pcDest = ( volatile unsigned char * ) pvDest, *pcSource = ( volatile unsigned char * ) pvSource;
|
||||||
|
size_t x;
|
||||||
|
|
||||||
|
/* Extremely crude standard library implementations in lieu of having a C
|
||||||
|
library. */
|
||||||
|
if( pvDest != pvSource )
|
||||||
|
{
|
||||||
|
for( x = 0; x < xBytes; x++ )
|
||||||
|
{
|
||||||
|
pcDest[ x ] = pcSource[ x ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pvDest;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void *memset( void *pvDest, int iValue, size_t xBytes )
|
||||||
|
{
|
||||||
|
/* The compiler used during development seems to err unless these volatiles are
|
||||||
|
included at -O3 optimisation. */
|
||||||
|
volatile unsigned char * volatile pcDest = ( volatile unsigned char * volatile ) pvDest;
|
||||||
|
volatile size_t x;
|
||||||
|
|
||||||
|
/* Extremely crude standard library implementations in lieu of having a C
|
||||||
|
library. */
|
||||||
|
for( x = 0; x < xBytes; x++ )
|
||||||
|
{
|
||||||
|
pcDest[ x ] = ( unsigned char ) iValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pvDest;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
int memcmp( const void *pvMem1, const void *pvMem2, unsigned long ulBytes )
|
||||||
|
{
|
||||||
|
const volatile unsigned char *pucMem1 = pvMem1, *pucMem2 = pvMem2;
|
||||||
|
register unsigned long x;
|
||||||
|
|
||||||
|
/* Extremely crude standard library implementations in lieu of having a C
|
||||||
|
library. */
|
||||||
|
for( x = 0; x < ulBytes; x++ )
|
||||||
|
{
|
||||||
|
if( pucMem1[ x ] != pucMem2[ x ] )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ulBytes - x;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
int strcmp( const char *pcString1, const char *pcString2 )
|
||||||
|
{
|
||||||
|
volatile int iReturn, iIndex = 0;
|
||||||
|
|
||||||
|
/* Extremely crude standard library implementations in lieu of having a C
|
||||||
|
library. */
|
||||||
|
|
||||||
|
while( ( pcString1[ iIndex ] != 0x00 ) && ( pcString2[ iIndex ] != 0x00 ) )
|
||||||
|
{
|
||||||
|
iIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( pcString1[ iIndex ] == 0x00 ) && ( pcString2[ iIndex ] == 0x00 ) )
|
||||||
|
{
|
||||||
|
iReturn = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iReturn = ~0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return iReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,550 @@
|
|||||||
|
/*--------------------------------------------------------------------
|
||||||
|
Copyright(c) 2015 Intel Corporation. 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 Intel Corporation nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
--------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Any required includes
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "multiboot.h"
|
||||||
|
#include "galileo_support.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Any required local definitions
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL (void *)0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MUTEX_WAIT_TIME (( TickType_t ) 8 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Function prototypes
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
extern void *memcpy( void *pvDest, const void *pvSource, unsigned long ulBytes );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Global variables
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
uint32_t bootinfo = 1UL;
|
||||||
|
uint32_t bootsign = 1UL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Static variables
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static uint32_t bGalileoSerialPortInitialized = FALSE;
|
||||||
|
static uint32_t uiLEDBlinkState = LED_OFF;
|
||||||
|
static uint16_t usIRQMask = 0xfffb;
|
||||||
|
static uint32_t UART_PCI_Base = 0UL;
|
||||||
|
static uint32_t UART_MMIO_Base = 0UL;
|
||||||
|
static SemaphoreHandle_t semPrintfGate = 0;
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
* GDT default entries (used in GDT setup code)
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static struct sd gdt_default[NGDE] =
|
||||||
|
{
|
||||||
|
/* sd_lolimit sd_lobase sd_midbase sd_access sd_hilim_fl sd_hibase */
|
||||||
|
/* 0th entry NULL */
|
||||||
|
{ 0, 0, 0, 0, 0, 0, },
|
||||||
|
/* 1st, Kernel Code Segment */
|
||||||
|
{ 0xffff, 0, 0, 0x9a, 0xcf, 0, },
|
||||||
|
/* 2nd, Kernel Data Segment */
|
||||||
|
{ 0xffff, 0, 0, 0x92, 0xcf, 0, },
|
||||||
|
/* 3rd, Kernel Stack Segment */
|
||||||
|
{ 0xffff, 0, 0, 0x92, 0xcf, 0, },
|
||||||
|
/* 4st, Boot Code Segment */
|
||||||
|
{ 0xffff, 0, 0, 0x9a, 0xcf, 0, },
|
||||||
|
/* 5th, Code Segment for BIOS32 request */
|
||||||
|
{ 0xffff, 0, 0, 0x9a, 0xcf, 0, },
|
||||||
|
/* 6th, Data Segment for BIOS32 request */
|
||||||
|
{ 0xffff, 0, 0, 0x92, 0xcf, 0, },
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct sd gdt[]; /* Global segment table (defined in startup.S) */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
* Set segment registers (used in GDT setup code)
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void setsegs()
|
||||||
|
{
|
||||||
|
extern int __text_end;
|
||||||
|
struct sd *psd;
|
||||||
|
uint32_t np, ds_end;
|
||||||
|
|
||||||
|
ds_end = 0xffffffff/PAGE_SIZE; /* End page number */
|
||||||
|
|
||||||
|
psd = &gdt_default[1]; /* Kernel code segment */
|
||||||
|
np = ((int)&__text_end - 0 + PAGE_SIZE-1) / PAGE_SIZE; /* Number of code pages */
|
||||||
|
psd->sd_lolimit = np;
|
||||||
|
psd->sd_hilim_fl = FLAGS_SETTINGS | ((np >> 16) & 0xff);
|
||||||
|
|
||||||
|
psd = &gdt_default[2]; /* Kernel data segment */
|
||||||
|
psd->sd_lolimit = ds_end;
|
||||||
|
psd->sd_hilim_fl = FLAGS_SETTINGS | ((ds_end >> 16) & 0xff);
|
||||||
|
|
||||||
|
psd = &gdt_default[3]; /* Kernel stack segment */
|
||||||
|
psd->sd_lolimit = ds_end;
|
||||||
|
psd->sd_hilim_fl = FLAGS_SETTINGS | ((ds_end >> 16) & 0xff);
|
||||||
|
|
||||||
|
psd = &gdt_default[4]; /* Boot code segment */
|
||||||
|
psd->sd_lolimit = ds_end;
|
||||||
|
psd->sd_hilim_fl = FLAGS_SETTINGS | ((ds_end >> 16) & 0xff);
|
||||||
|
|
||||||
|
memcpy(gdt, gdt_default, sizeof(gdt_default));
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Debug serial port display update functions
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static void vCreatePrintfSemaphore( void )
|
||||||
|
{
|
||||||
|
if (semPrintfGate == 0)
|
||||||
|
{
|
||||||
|
semPrintfGate = xSemaphoreCreateRecursiveMutex();
|
||||||
|
vQueueAddToRegistry( ( QueueHandle_t ) semPrintfGate, "g_printf_Mutex" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void ClearScreen(void)
|
||||||
|
{
|
||||||
|
g_printf(ANSI_CLEAR_SB);
|
||||||
|
g_printf(ANSI_CLEAR_SCREEN);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void MoveToScreenPosition(uint8_t row, uint8_t col)
|
||||||
|
{
|
||||||
|
g_printf("%c[%d;%dH", (char) 0x1B, row, col);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void UngatedMoveToScreenPosition(uint8_t row, uint8_t col)
|
||||||
|
{
|
||||||
|
printf("%c[%d;%dH", (char) 0x1B, row, col);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SetScreenColor(const char *color)
|
||||||
|
{
|
||||||
|
g_printf("%s", color);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void g_printf(const char *format, ...)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (semPrintfGate == 0)
|
||||||
|
vCreatePrintfSemaphore();
|
||||||
|
|
||||||
|
if (xSemaphoreTakeRecursive(semPrintfGate, MUTEX_WAIT_TIME))
|
||||||
|
{
|
||||||
|
va_list arguments;
|
||||||
|
va_start(arguments,format);
|
||||||
|
print(0, format, arguments);
|
||||||
|
xSemaphoreGiveRecursive(semPrintfGate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void g_printf_rcc(uint8_t row, uint8_t col, const char *color, const char *format, ...)
|
||||||
|
{
|
||||||
|
if (semPrintfGate == 0)
|
||||||
|
vCreatePrintfSemaphore();
|
||||||
|
|
||||||
|
if (xSemaphoreTakeRecursive(semPrintfGate, MUTEX_WAIT_TIME ))
|
||||||
|
{
|
||||||
|
UngatedMoveToScreenPosition(row, col);
|
||||||
|
printf("%s",color);
|
||||||
|
va_list arguments;
|
||||||
|
va_start(arguments,format);
|
||||||
|
print(0, format, arguments);
|
||||||
|
xSemaphoreGiveRecursive(semPrintfGate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPrintBanner( void )
|
||||||
|
{
|
||||||
|
if (bGalileoSerialPortInitialized)
|
||||||
|
{
|
||||||
|
/* Print an RTOSDemo Loaded message */
|
||||||
|
ClearScreen();
|
||||||
|
g_printf_rcc(1, 2, DEFAULT_BANNER_COLOR,
|
||||||
|
"%c[1mHELLO from the multiboot compliant FreeRTOS kernel!%c[0m",
|
||||||
|
(char) 0x1B, (char) 0x1B );
|
||||||
|
printf(ANSI_HIDE_CURSOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
* Multiboot support (show parameters passed back from GRUB)
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void show_kernel_parameters( unsigned long magic, unsigned long addr )
|
||||||
|
{
|
||||||
|
/* Set to 0 to quiet display. */
|
||||||
|
uint8_t print_values = 1;
|
||||||
|
|
||||||
|
/* Initialise serial port if necessary. */
|
||||||
|
vInitializeGalileoSerialPort(DEBUG_SERIAL_PORT);
|
||||||
|
|
||||||
|
if (print_values != 0)
|
||||||
|
{
|
||||||
|
ClearScreen();
|
||||||
|
g_printf(DEFAULT_SCREEN_COLOR);
|
||||||
|
MoveToScreenPosition(1, 2);
|
||||||
|
g_printf ("\n\r ...MULTIBOOT VALUES RETURNED FROM GRUB...\n\n\r");
|
||||||
|
g_printf(ANSI_COLOR_WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
|
||||||
|
{
|
||||||
|
printf(ANSI_COLOR_RED);
|
||||||
|
if (print_values != 0)
|
||||||
|
g_printf (" Invalid magic number returned: 0x%08x\n\r", (unsigned) magic);
|
||||||
|
g_printf(ANSI_COLOR_RESET);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
multiboot_info_t *mbi;
|
||||||
|
/* Set MBI to the address of the Multiboot information structure. */
|
||||||
|
mbi = (multiboot_info_t *) addr;
|
||||||
|
|
||||||
|
/* Is the command line passed? */
|
||||||
|
if (CHECK_FLAG (mbi->flags, 2))
|
||||||
|
if (print_values != 0)
|
||||||
|
g_printf (" cmdline = %s\n\r", (char *) mbi->cmdline);
|
||||||
|
|
||||||
|
/* Print out the flags. */
|
||||||
|
if (print_values != 0)
|
||||||
|
g_printf (" flags = 0x%08x\n\r", (unsigned) mbi->flags);
|
||||||
|
|
||||||
|
/* Are mem_* valid? */
|
||||||
|
if (CHECK_FLAG (mbi->flags, 0))
|
||||||
|
if (print_values != 0)
|
||||||
|
g_printf (" mem_lower = %u KB, mem_upper = %u KB\n\r",
|
||||||
|
(unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper);
|
||||||
|
|
||||||
|
/* Is boot_device valid? */
|
||||||
|
if (CHECK_FLAG (mbi->flags, 1))
|
||||||
|
if (print_values != 0)
|
||||||
|
g_printf (" boot_device = 0x%08x\n\r", (unsigned) mbi->boot_device);
|
||||||
|
|
||||||
|
if (CHECK_FLAG (mbi->flags, 3))
|
||||||
|
{
|
||||||
|
module_t *mod;
|
||||||
|
int i;
|
||||||
|
if (print_values != 0)
|
||||||
|
g_printf (" mods_count = %d, mods_addr = 0x%08x\n\r",
|
||||||
|
(int) mbi->mods_count, (int) mbi->mods_addr);
|
||||||
|
for (i = 0, mod = (module_t *) mbi->mods_addr;
|
||||||
|
i < (int)mbi->mods_count;
|
||||||
|
i++, mod++)
|
||||||
|
{
|
||||||
|
if (print_values != 0)
|
||||||
|
g_printf (" mod_start = 0x%08x, mod_end = 0x%08x, cmdline = %s\n\r",
|
||||||
|
(unsigned) mod->mod_start,
|
||||||
|
(unsigned) mod->mod_end,
|
||||||
|
(char *) mod->string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bits 4 and 5 are mutually exclusive! */
|
||||||
|
if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5))
|
||||||
|
{
|
||||||
|
if (print_values != 0)
|
||||||
|
g_printf (" Both bits 4 and 5 are set.\n\r");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Is the symbol table of a.out valid? */
|
||||||
|
if (CHECK_FLAG (mbi->flags, 4))
|
||||||
|
{
|
||||||
|
aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym);
|
||||||
|
if (print_values != 0)
|
||||||
|
g_printf (" multiboot_aout_symbol_table: tabsize = 0x%08x, "
|
||||||
|
"strsize = 0x%08x, addr = 0x%08x\n\r",
|
||||||
|
(unsigned) multiboot_aout_sym->tabsize,
|
||||||
|
(unsigned) multiboot_aout_sym->strsize,
|
||||||
|
(unsigned) multiboot_aout_sym->addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is the section header table of ELF valid? */
|
||||||
|
if (CHECK_FLAG (mbi->flags, 5))
|
||||||
|
{
|
||||||
|
elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec);
|
||||||
|
if (print_values != 0)
|
||||||
|
g_printf (" multiboot_elf_sec: num = %u, size = 0x%08x,"
|
||||||
|
" addr = 0x%08x, shndx = 0x%04x\n\r",
|
||||||
|
(unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size,
|
||||||
|
(unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Are mmap_* valid? */
|
||||||
|
if (CHECK_FLAG (mbi->flags, 6))
|
||||||
|
{
|
||||||
|
memory_map_t *mmap;
|
||||||
|
if (print_values != 0)
|
||||||
|
g_printf (" mmap_addr = 0x%08x, mmap_length = 0x%08x\n\r",
|
||||||
|
(unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length);
|
||||||
|
for (mmap = (memory_map_t *) mbi->mmap_addr;
|
||||||
|
(unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
|
||||||
|
mmap = (memory_map_t *) ((unsigned long) mmap
|
||||||
|
+ mmap->size + sizeof (mmap->size)))
|
||||||
|
{
|
||||||
|
if (print_values != 0)
|
||||||
|
g_printf (" size = 0x%08x, base_addr = 0x%04x%04x,"
|
||||||
|
" length = 0x%04x%04x, type = 0x%04x\n\r",
|
||||||
|
(unsigned) mmap->size,
|
||||||
|
(uint16_t) mmap->base_addr_high,
|
||||||
|
(uint16_t)mmap->base_addr_low,
|
||||||
|
(uint16_t)mmap->length_high,
|
||||||
|
(uint16_t)mmap->length_low,
|
||||||
|
(unsigned) mmap->type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (print_values != 0)
|
||||||
|
{
|
||||||
|
g_printf(DEFAULT_SCREEN_COLOR);
|
||||||
|
g_printf ("\n\r Press any key to continue.\n\r");
|
||||||
|
while (ucGalileoGetchar() == 0)
|
||||||
|
{
|
||||||
|
__asm volatile( "NOP" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
main();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
* 8259 PIC initialization and support code
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void vInitialize8259Chips(void)
|
||||||
|
{
|
||||||
|
/* Set interrupt mask */
|
||||||
|
uint16_t IRQMask = 0xffff;
|
||||||
|
outb(IMR1, (uint8_t) (IRQMask & 0xff));
|
||||||
|
outb(IMR2, (uint8_t) ((IRQMask >> 8) & 0xff));
|
||||||
|
|
||||||
|
/* Initialise the 8259A interrupt controllers */
|
||||||
|
|
||||||
|
/* Master device */
|
||||||
|
outb(ICU1, 0x11); /* ICW1: icw4 needed */
|
||||||
|
outb(ICU1+1, 0x20); /* ICW2: base ivec 32 */
|
||||||
|
outb(ICU1+1, 0x4); /* ICW3: cascade on irq2 */
|
||||||
|
outb(ICU1+1, 0x1); /* ICW4: buf. master, 808x mode */
|
||||||
|
|
||||||
|
/* Slave device */
|
||||||
|
outb(ICU2, 0x11); /* ICW1: icw4 needed */
|
||||||
|
outb(ICU2+1, 0x28); /* ICW2: base ivec 40 */
|
||||||
|
outb(ICU2+1, 0x2); /* ICW3: slave on irq2 */
|
||||||
|
outb(ICU2+1, 0xb); /* ICW4: buf. slave, 808x mode */
|
||||||
|
|
||||||
|
vMicroSecondDelay (100);
|
||||||
|
|
||||||
|
/* always read ISR */
|
||||||
|
outb(ICU1, 0xb); /* OCW3: set ISR on read */
|
||||||
|
outb(ICU2, 0xb); /* OCW3: set ISR on read */
|
||||||
|
|
||||||
|
/* Set interrupt mask - leave bit 2 enabled for IC cascade */
|
||||||
|
IRQMask = 0xfffb;
|
||||||
|
outb(IMR1, (uint8_t) (IRQMask & 0xff));
|
||||||
|
outb(IMR2, (uint8_t) ((IRQMask >> 8) & 0xff));
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vClearIRQMask(uint8_t IRQNumber)
|
||||||
|
{
|
||||||
|
if( ( IRQNumber > 31 ) && ( IRQNumber < 48 ) )
|
||||||
|
{
|
||||||
|
usIRQMask &= ~( 1 << (IRQNumber - 32 ) );
|
||||||
|
usIRQMask &= 0xfffb; // bit 2 is slave cascade
|
||||||
|
usIRQMask |= 0x0200; // bit 14 is reserved
|
||||||
|
outb(IMR1, (uint8_t) (usIRQMask & 0xff));
|
||||||
|
outb(IMR2, (uint8_t) ((usIRQMask >> 8) & 0xff));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vSetIRQMask(uint8_t IRQNumber)
|
||||||
|
{
|
||||||
|
if( ( IRQNumber > 31 ) && ( IRQNumber < 48 ) )
|
||||||
|
{
|
||||||
|
usIRQMask |= ( 1 << (IRQNumber - 32 ) );
|
||||||
|
usIRQMask &= 0xfffb; // bit 2 is slave cascade
|
||||||
|
usIRQMask |= 0x0200; // bit 14 is reserved
|
||||||
|
outb(IMR1, (uint8_t) (usIRQMask & 0xff));
|
||||||
|
outb(IMR2, (uint8_t) ((usIRQMask >> 8) & 0xff));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* 82C54 PIT (programmable interval timer) initialization
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void vInitializePIT(void)
|
||||||
|
{
|
||||||
|
/* Set the hardware clock: timer 0, 16-bit counter, rate */
|
||||||
|
/* generator mode, and counter runs in binary */
|
||||||
|
outb(CLKCNTL, 0x34);
|
||||||
|
|
||||||
|
/* Set the clock rate to 1.193 Mhz, this is 1 ms interrupt rate */
|
||||||
|
uint16_t intrate = 1193;
|
||||||
|
/* Must write LSB first, then MSB */
|
||||||
|
outb(CLKBASE, (char) (intrate & 0xff));
|
||||||
|
outb(CLKBASE, (char) ((intrate >> 8) & 0xff));
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* LED support for main_blinky()
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
uint32_t ulBlinkLED(void)
|
||||||
|
{
|
||||||
|
if( uiLEDBlinkState == LED_OFF )
|
||||||
|
{
|
||||||
|
uiLEDBlinkState = LED_ON;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uiLEDBlinkState = LED_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
vGalileoBlinkLEDUsingLegacyGPIO(uiLEDBlinkState);
|
||||||
|
|
||||||
|
return uiLEDBlinkState;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Serial port initialization code
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static void vInitializeGalileoUART(uint32_t portnumber)
|
||||||
|
{
|
||||||
|
volatile uint8_t divisor = 24;
|
||||||
|
volatile uint8_t output_data = 0x3 & 0xFB & 0xF7;
|
||||||
|
volatile uint8_t input_data = 0;
|
||||||
|
volatile uint8_t lcr = 0;
|
||||||
|
|
||||||
|
if (portnumber == DEBUG_SERIAL_PORT)
|
||||||
|
UART_PCI_Base = MMIO_PCI_ADDRESS(0, 20, 5, 0);
|
||||||
|
else
|
||||||
|
UART_PCI_Base = MMIO_PCI_ADDRESS(0, 20, 1, 0);
|
||||||
|
|
||||||
|
uint32_t base = mem_read(UART_PCI_Base, 0x10, 4);
|
||||||
|
UART_MMIO_Base = base;
|
||||||
|
|
||||||
|
mem_write(base, R_UART_SCR, 1, 0xAB);
|
||||||
|
|
||||||
|
mem_write(base, R_UART_LCR, 1, output_data | B_UARY_LCR_DLAB);
|
||||||
|
|
||||||
|
mem_write(base, R_UART_BAUD_HIGH, 1, (uint8_t)(divisor >> 8));
|
||||||
|
mem_write(base, R_UART_BAUD_LOW, 1, (uint8_t)(divisor & 0xff));
|
||||||
|
|
||||||
|
mem_write(base, R_UART_LCR, 1, output_data);
|
||||||
|
|
||||||
|
mem_write(base, R_UART_FCR, 1, (uint8_t)(B_UARY_FCR_TRFIFIE |
|
||||||
|
B_UARY_FCR_RESETRF | B_UARY_FCR_RESETTF | 0x30));
|
||||||
|
|
||||||
|
input_data = mem_read(base, R_UART_MCR, 1);
|
||||||
|
input_data |= BIT1;
|
||||||
|
input_data &= ~BIT5;
|
||||||
|
mem_write(base, R_UART_MCR, 1, input_data);
|
||||||
|
|
||||||
|
lcr = mem_read(base, R_UART_LCR, 1);
|
||||||
|
mem_write(base, R_UART_LCR, 1, (uint8_t) (lcr & ~B_UARY_LCR_DLAB));
|
||||||
|
|
||||||
|
mem_write(base, R_UART_IER, 1, 0);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vInitializeGalileoSerialPort(uint32_t portnumber)
|
||||||
|
{
|
||||||
|
if( bGalileoSerialPortInitialized == FALSE )
|
||||||
|
{
|
||||||
|
/* Initialise for 115200, 8, 1, none and no handshaking */
|
||||||
|
vInitializeGalileoUART(portnumber);
|
||||||
|
bGalileoSerialPortInitialized = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Serial port support functions
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void vGalileoPrintc(char c)
|
||||||
|
{
|
||||||
|
if (bGalileoSerialPortInitialized)
|
||||||
|
{
|
||||||
|
while((mem_read(UART_MMIO_Base, R_UART_LSR, 1) & B_UART_LSR_TXRDY) == 0);
|
||||||
|
mem_write(UART_MMIO_Base, R_UART_BAUD_THR, 1, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
uint8_t ucGalileoGetchar()
|
||||||
|
{
|
||||||
|
uint8_t c = 0;
|
||||||
|
if (bGalileoSerialPortInitialized)
|
||||||
|
{
|
||||||
|
if((mem_read(UART_MMIO_Base, R_UART_LSR, 1) & B_UART_LSR_RXRDY) != 0)
|
||||||
|
c = mem_read(UART_MMIO_Base, R_UART_BAUD_THR, 1);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vGalileoPuts(const char *string)
|
||||||
|
{
|
||||||
|
if (bGalileoSerialPortInitialized)
|
||||||
|
{
|
||||||
|
while(*string)
|
||||||
|
vGalileoPrintc(*string++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
@ -0,0 +1,216 @@
|
|||||||
|
/*--------------------------------------------------------------------
|
||||||
|
Copyright(c) 2015 Intel Corporation. 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 Intel Corporation nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
--------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __GALILEO_GEN_DEFS_H__
|
||||||
|
#define __GALILEO_GEN_DEFS_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Any required includes
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Printf prototype
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
extern int printf( const char *format, ... );
|
||||||
|
extern int print( char **out, const char *format, va_list args );
|
||||||
|
extern int sprintf(char *out, const char *format, ...);
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Prototypes (assembly language functions in startup.S)
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
extern void halt( void );
|
||||||
|
extern int32_t inb( int32_t );
|
||||||
|
extern int32_t inw( int32_t );
|
||||||
|
extern int32_t inl( int32_t );
|
||||||
|
extern int32_t outb( int32_t, int32_t );
|
||||||
|
extern int32_t outw( int32_t, int32_t );
|
||||||
|
extern int32_t outl( int32_t, int32_t) ;
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// GP definitions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE ( 1 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE ( 0 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef true
|
||||||
|
#define true TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef false
|
||||||
|
#define false FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef OK
|
||||||
|
#define OK TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// General bit pattern definitions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define BIT0 0x00000001U
|
||||||
|
#define BIT1 0x00000002U
|
||||||
|
#define BIT2 0x00000004U
|
||||||
|
#define BIT3 0x00000008U
|
||||||
|
#define BIT4 0x00000010U
|
||||||
|
#define BIT5 0x00000020U
|
||||||
|
#define BIT6 0x00000040U
|
||||||
|
#define BIT7 0x00000080U
|
||||||
|
#define BIT8 0x00000100U
|
||||||
|
#define BIT9 0x00000200U
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// MMIO support definitions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define EC_BASE 0xE0000000 /* Base of MMConfig space */
|
||||||
|
#define MMCONFIG_BASE EC_BASE
|
||||||
|
#define MMIO_PCI_ADDRESS(bus,dev,fn,reg) ( \
|
||||||
|
(EC_BASE) + \
|
||||||
|
((bus) << 20) + \
|
||||||
|
((dev) << 15) + \
|
||||||
|
((fn) << 12) + \
|
||||||
|
(reg))
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// MMIO read/write/set/clear/modify macros
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define mem_read(base, offset, size) ({ \
|
||||||
|
volatile uint32_t a = (base) + (offset); \
|
||||||
|
volatile uint64_t v; \
|
||||||
|
switch (size) { \
|
||||||
|
case 1: \
|
||||||
|
v = (uint8_t)(*((uint8_t *)a)); \
|
||||||
|
break; \
|
||||||
|
case 2: \
|
||||||
|
v = (uint16_t)(*((uint16_t *)a)); \
|
||||||
|
break; \
|
||||||
|
case 4: \
|
||||||
|
v = (uint32_t)(*((uint32_t *)a)); \
|
||||||
|
break; \
|
||||||
|
case 8: \
|
||||||
|
v = (uint64_t)(*((uint64_t *)a)); \
|
||||||
|
break; \
|
||||||
|
default: \
|
||||||
|
halt(); \
|
||||||
|
} \
|
||||||
|
v; \
|
||||||
|
})
|
||||||
|
|
||||||
|
// No cache bypass necessary -- MTRRs should handle this
|
||||||
|
#define mem_write(base, offset, size, value) { \
|
||||||
|
volatile uint32_t a = (base) + (offset); \
|
||||||
|
switch (size) { \
|
||||||
|
case 1: \
|
||||||
|
*((uint8_t *)a) = (uint8_t)(value); \
|
||||||
|
break; \
|
||||||
|
case 2: \
|
||||||
|
*((uint16_t *)a) = (uint16_t)(value); \
|
||||||
|
break; \
|
||||||
|
case 4: \
|
||||||
|
*((uint32_t *)a) = (uint32_t)(value); \
|
||||||
|
break; \
|
||||||
|
case 8: \
|
||||||
|
*((uint64_t *)a) = (uint64_t)(value); \
|
||||||
|
break; \
|
||||||
|
default: \
|
||||||
|
halt(); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define mem_set(base, offset, size, smask) { \
|
||||||
|
volatile uint32_t a = (base) + (offset); \
|
||||||
|
switch (size) { \
|
||||||
|
case 1: \
|
||||||
|
*((uint8_t *)a) = (uint8_t)((*((uint8_t *)a)) | (smask)); \
|
||||||
|
break; \
|
||||||
|
case 2: \
|
||||||
|
*((uint16_t *)a) = (uint16_t)((*((uint16_t *)a)) | (smask)); \
|
||||||
|
break; \
|
||||||
|
case 4: \
|
||||||
|
*((uint32_t *)a) = (uint32_t)((*((uint32_t *)a)) | (smask)); \
|
||||||
|
break; \
|
||||||
|
case 8: \
|
||||||
|
*((uint64_t *)a) = (uint64_t)((*((uint64_t *)a)) | (smask)); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define mem_clear(base, offset, size, cmask) { \
|
||||||
|
volatile uint32_t a = (base) + (offset); \
|
||||||
|
switch (size) { \
|
||||||
|
case 1: \
|
||||||
|
*((uint8_t *)a) = (uint8_t)((*((uint8_t *)a) & ~(cmask))); \
|
||||||
|
break; \
|
||||||
|
case 2: \
|
||||||
|
*((uint16_t *)a) = (uint16_t)((*((uint16_t *)a) & ~(cmask))); \
|
||||||
|
break; \
|
||||||
|
case 4: \
|
||||||
|
*((uint32_t *)a) = (uint32_t)((*((uint32_t *)a) & ~(cmask))); \
|
||||||
|
break; \
|
||||||
|
case 8: \
|
||||||
|
*((uint64_t *)a) = (uint64_t)((*((uint64_t *)a) & ~(cmask))); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define mem_modify(base, offset, size, cmask, smask) { \
|
||||||
|
volatile uint32_t a = (base) + (offset); \
|
||||||
|
switch (size) { \
|
||||||
|
case 1: \
|
||||||
|
*((uint8_t *)a) = (uint8_t)((*((uint8_t *)a) & ~(cmask)) | (smask)); \
|
||||||
|
break; \
|
||||||
|
case 2: \
|
||||||
|
*((uint16_t *)a) = (uint16_t)((*((uint16_t *)a) & ~(cmask)) | (smask)); \
|
||||||
|
break; \
|
||||||
|
case 4: \
|
||||||
|
*((uint32_t *)a) = (uint32_t)((*((uint32_t *)a) & ~(cmask)) | (smask)); \
|
||||||
|
break; \
|
||||||
|
case 8: \
|
||||||
|
*((uint64_t *)a) = (uint64_t)((*((uint64_t *)a) & ~(cmask)) | (smask)); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern C */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* GALILEO_GEN_DEFS */
|
||||||
|
|
@ -0,0 +1,174 @@
|
|||||||
|
/*--------------------------------------------------------------------
|
||||||
|
Copyright(c) 2015 Intel Corporation. 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 Intel Corporation nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
--------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __GALILEO_SUPPORT_H__
|
||||||
|
#define __GALILEO_SUPPORT_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Any required includes
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
#include "galileo_gen_defs.h"
|
||||||
|
#include "GPIO_I2C.h"
|
||||||
|
#include "HPET.h"
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Application main entry point
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
extern int main( void );
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Defines for GDT
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define NGDE 8 /* Number of global descriptor entries */
|
||||||
|
#define FLAGS_GRANULARITY 0x80
|
||||||
|
#define FLAGS_SIZE 0x40
|
||||||
|
#define FLAGS_SETTINGS ( FLAGS_GRANULARITY | FLAGS_SIZE )
|
||||||
|
#define PAGE_SIZE 4096
|
||||||
|
|
||||||
|
struct __attribute__ ((__packed__)) sd
|
||||||
|
{
|
||||||
|
unsigned short sd_lolimit;
|
||||||
|
unsigned short sd_lobase;
|
||||||
|
unsigned char sd_midbase;
|
||||||
|
unsigned char sd_access;
|
||||||
|
unsigned char sd_hilim_fl;
|
||||||
|
unsigned char sd_hibase;
|
||||||
|
};
|
||||||
|
|
||||||
|
void setsegs();
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Debug serial port display update definitions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define ANSI_CLEAR_SB "\e[3J"
|
||||||
|
#define ANSI_CLEAR_LINE "\x1b[2K"
|
||||||
|
#define ANSI_CLEAR_SCREEN "\x1b[2J"
|
||||||
|
#define ANSI_COLOR_RED "\x1b[31m"
|
||||||
|
#define ANSI_COLOR_GREEN "\x1b[32m"
|
||||||
|
#define ANSI_COLOR_YELLOW "\x1b[33m"
|
||||||
|
#define ANSI_COLOR_BLUE "\x1b[34m"
|
||||||
|
#define ANSI_COLOR_MAGENTA "\x1b[35m"
|
||||||
|
#define ANSI_COLOR_CYAN "\x1b[36m"
|
||||||
|
#define ANSI_COLOR_RESET "\x1b[0m"
|
||||||
|
#define ANSI_COLOR_WHITE ANSI_COLOR_RESET
|
||||||
|
|
||||||
|
#define DEFAULT_SCREEN_COLOR ANSI_COLOR_YELLOW
|
||||||
|
#define DEFAULT_BANNER_COLOR ANSI_COLOR_CYAN
|
||||||
|
|
||||||
|
#define ANSI_HIDE_CURSOR "\x1b[?25l"
|
||||||
|
#define ANSI_SHOW_CURSOR "\x1b[?25h"
|
||||||
|
|
||||||
|
void ClearScreen(void);
|
||||||
|
void MoveToScreenPosition(uint8_t row, uint8_t col);
|
||||||
|
void UngatedMoveToScreenPosition(uint8_t row, uint8_t col);
|
||||||
|
void SetScreenColor(const char *);
|
||||||
|
void g_printf(const char *format, ...);
|
||||||
|
void g_printf_rcc(uint8_t row, uint8_t col, const char *color, const char *format, ...);
|
||||||
|
void vPrintBanner( void );
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// 8259 PIC (programmable interrupt controller) definitions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define IMR1 (0x21) /* Interrupt Mask Register #1 */
|
||||||
|
#define IMR2 (0xA1) /* Interrupt Mask Register #2 */
|
||||||
|
#define ICU1 (0x20)
|
||||||
|
#define ICU2 (0xA0)
|
||||||
|
#define EOI (0x20)
|
||||||
|
|
||||||
|
void vInitialize8259Chips(void);
|
||||||
|
void vClearIRQMask(uint8_t IRQNumber);
|
||||||
|
void vSetIRQMask(uint8_t IRQNumber);
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// 82C54 PIT (programmable interval timer) definitions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define GATE_CONTROL 0x61
|
||||||
|
#define CHANNEL2_DATA 0x42
|
||||||
|
#define MODE_REGISTER 0x43
|
||||||
|
#define ONESHOT_MODE 0xB2
|
||||||
|
#define CLKBASE 0x40
|
||||||
|
#define CLKCNTL MODE_REGISTER
|
||||||
|
|
||||||
|
void vInitializePIT(void);
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// LED support for main_blinky()
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define LED_ON ( 1 )
|
||||||
|
#define LED_OFF ( 0 )
|
||||||
|
|
||||||
|
uint32_t ulBlinkLED(void); /* Blink the LED and return the LED status. */
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Serial port support definitions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
#define CLIENT_SERIAL_PORT 0
|
||||||
|
#define DEBUG_SERIAL_PORT 1
|
||||||
|
|
||||||
|
#define R_UART_THR 0
|
||||||
|
#define R_UART_IER 0x04
|
||||||
|
#define R_UART_BAUD_THR R_UART_THR
|
||||||
|
#define R_UART_BAUD_LOW R_UART_BAUD_THR
|
||||||
|
#define R_UART_BAUD_HIGH R_UART_IER
|
||||||
|
#define R_UART_FCR 0x08
|
||||||
|
#define B_UARY_FCR_TRFIFIE BIT0
|
||||||
|
#define B_UARY_FCR_RESETRF BIT1
|
||||||
|
#define B_UARY_FCR_RESETTF BIT2
|
||||||
|
#define R_UART_LCR 0x0C
|
||||||
|
#define B_UARY_LCR_DLAB BIT7
|
||||||
|
#define R_UART_MCR 0x10
|
||||||
|
#define R_UART_LSR 0x14
|
||||||
|
#define B_UART_LSR_RXRDY BIT0
|
||||||
|
#define B_UART_LSR_OE BIT1
|
||||||
|
#define B_UART_LSR_PE BIT2
|
||||||
|
#define B_UART_LSR_FE BIT3
|
||||||
|
#define B_UART_LSR_BI BIT4
|
||||||
|
#define B_UART_LSR_TXRDY BIT5
|
||||||
|
#define B_UART_LSR_TEMT BIT6
|
||||||
|
#define R_UART_MSR 0x18
|
||||||
|
#define R_UART_SCR 0x1C
|
||||||
|
|
||||||
|
void vInitializeGalileoSerialPort(uint32_t portnumber);
|
||||||
|
void vGalileoPrintc(char c);
|
||||||
|
uint8_t ucGalileoGetchar();
|
||||||
|
void vGalileoPuts(const char *string);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern C */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __GALILEO_SUPPORT_H__ */
|
||||||
|
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MATH_H
|
||||||
|
#define MATH_H
|
||||||
|
|
||||||
|
double fabs( double x );
|
||||||
|
|
||||||
|
#endif /* math_h */
|
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Multiboot OS definitions and structures.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MULTIBOOT_H_
|
||||||
|
#define _MULTIBOOT_H_
|
||||||
|
|
||||||
|
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
|
||||||
|
#define MULTIBOOT_HEADER_FLAGS 0x00010003
|
||||||
|
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
|
||||||
|
|
||||||
|
typedef unsigned long t_32 ;
|
||||||
|
|
||||||
|
typedef struct multiboot_header
|
||||||
|
{
|
||||||
|
t_32 Magic;
|
||||||
|
t_32 flags;
|
||||||
|
t_32 checksum;
|
||||||
|
t_32 header_addr;
|
||||||
|
t_32 load_addr;
|
||||||
|
t_32 load_end_addr;
|
||||||
|
t_32 bss_end_addr;
|
||||||
|
t_32 entry_addr;
|
||||||
|
t_32 video_mode;
|
||||||
|
t_32 width;
|
||||||
|
t_32 height;
|
||||||
|
t_32 depth;
|
||||||
|
} multiboot_header_t;
|
||||||
|
|
||||||
|
/* Symbol table for a.out. */
|
||||||
|
typedef struct aout_symbol_table
|
||||||
|
{
|
||||||
|
t_32 tabsize;
|
||||||
|
t_32 strsize;
|
||||||
|
t_32 addr;
|
||||||
|
t_32 reserved;
|
||||||
|
} aout_symbol_table_t;
|
||||||
|
|
||||||
|
/* Section header table for ELF. */
|
||||||
|
typedef struct elf_section_header_table
|
||||||
|
{
|
||||||
|
t_32 num;
|
||||||
|
t_32 size;
|
||||||
|
t_32 addr;
|
||||||
|
t_32 shndx;
|
||||||
|
} elf_section_header_table_t;
|
||||||
|
|
||||||
|
/* Multiboot information. */
|
||||||
|
typedef struct multiboot_info
|
||||||
|
{
|
||||||
|
t_32 flags;
|
||||||
|
t_32 mem_lower;
|
||||||
|
t_32 mem_upper;
|
||||||
|
t_32 boot_device;
|
||||||
|
t_32 cmdline;
|
||||||
|
t_32 mods_count;
|
||||||
|
t_32 mods_addr;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
aout_symbol_table_t aout_sym;
|
||||||
|
elf_section_header_table_t elf_sec;
|
||||||
|
} u;
|
||||||
|
t_32 mmap_length;
|
||||||
|
t_32 mmap_addr;
|
||||||
|
} multiboot_info_t;
|
||||||
|
|
||||||
|
/* Module structure. */
|
||||||
|
typedef struct module
|
||||||
|
{
|
||||||
|
t_32 mod_start;
|
||||||
|
t_32 mod_end;
|
||||||
|
t_32 string;
|
||||||
|
t_32 reserved;
|
||||||
|
} module_t;
|
||||||
|
|
||||||
|
/* Memory map. Offset 0 is base_addr_low -no size. */
|
||||||
|
typedef struct memory_map
|
||||||
|
{
|
||||||
|
t_32 size;
|
||||||
|
t_32 base_addr_low;
|
||||||
|
t_32 base_addr_high;
|
||||||
|
t_32 length_low;
|
||||||
|
t_32 length_high;
|
||||||
|
t_32 type;
|
||||||
|
} memory_map_t;
|
||||||
|
|
||||||
|
#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit)))
|
||||||
|
|
||||||
|
#endif /* _MULTIBOOT_H_ */
|
@ -0,0 +1,282 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2001, 2002 Georges Menie (www.menie.org)
|
||||||
|
stdarg version contributed by Christian Ettinger
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include "galileo_support.h"
|
||||||
|
|
||||||
|
static void printchar(char **str, int c)
|
||||||
|
{
|
||||||
|
if (str) {
|
||||||
|
**str = (char)c;
|
||||||
|
++(*str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vGalileoPrintc( c );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PAD_RIGHT 1
|
||||||
|
#define PAD_ZERO 2
|
||||||
|
|
||||||
|
static int prints(char **out, const char *string, int width, int pad)
|
||||||
|
{
|
||||||
|
register int pc = 0, padchar = ' ';
|
||||||
|
|
||||||
|
if (width > 0) {
|
||||||
|
register int len = 0;
|
||||||
|
register const char *ptr;
|
||||||
|
for (ptr = string; *ptr; ++ptr) ++len;
|
||||||
|
if (len >= width) width = 0;
|
||||||
|
else width -= len;
|
||||||
|
if (pad & PAD_ZERO) padchar = '0';
|
||||||
|
}
|
||||||
|
if (!(pad & PAD_RIGHT)) {
|
||||||
|
for ( ; width > 0; --width) {
|
||||||
|
printchar (out, padchar);
|
||||||
|
++pc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( ; *string ; ++string) {
|
||||||
|
printchar (out, *string);
|
||||||
|
++pc;
|
||||||
|
}
|
||||||
|
for ( ; width > 0; --width) {
|
||||||
|
printchar (out, padchar);
|
||||||
|
++pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the following should be enough for 32 bit int */
|
||||||
|
#define PRINT_BUF_LEN 12
|
||||||
|
|
||||||
|
static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
|
||||||
|
{
|
||||||
|
char print_buf[PRINT_BUF_LEN];
|
||||||
|
register char *s;
|
||||||
|
register int t, neg = 0, pc = 0;
|
||||||
|
register unsigned int u = (unsigned int)i;
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
print_buf[0] = '0';
|
||||||
|
print_buf[1] = '\0';
|
||||||
|
return prints (out, print_buf, width, pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sg && b == 10 && i < 0) {
|
||||||
|
neg = 1;
|
||||||
|
u = (unsigned int)-i;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = print_buf + PRINT_BUF_LEN-1;
|
||||||
|
*s = '\0';
|
||||||
|
|
||||||
|
while (u) {
|
||||||
|
t = (unsigned int)u % b;
|
||||||
|
if( t >= 10 )
|
||||||
|
t += letbase - '0' - 10;
|
||||||
|
*--s = (char)(t + '0');
|
||||||
|
u /= b;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (neg) {
|
||||||
|
if( width && (pad & PAD_ZERO) ) {
|
||||||
|
printchar (out, '-');
|
||||||
|
++pc;
|
||||||
|
--width;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*--s = '-';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pc + prints (out, s, width, pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print( char **out, const char *format, va_list args )
|
||||||
|
{
|
||||||
|
register int width, pad;
|
||||||
|
register int pc = 0;
|
||||||
|
char scr[2];
|
||||||
|
|
||||||
|
for (; *format != 0; ++format) {
|
||||||
|
if (*format == '%') {
|
||||||
|
++format;
|
||||||
|
width = pad = 0;
|
||||||
|
if (*format == '\0') break;
|
||||||
|
if (*format == '%') goto out;
|
||||||
|
if (*format == '-') {
|
||||||
|
++format;
|
||||||
|
pad = PAD_RIGHT;
|
||||||
|
}
|
||||||
|
while (*format == '0') {
|
||||||
|
++format;
|
||||||
|
pad |= PAD_ZERO;
|
||||||
|
}
|
||||||
|
for ( ; *format >= '0' && *format <= '9'; ++format) {
|
||||||
|
width *= 10;
|
||||||
|
width += *format - '0';
|
||||||
|
}
|
||||||
|
if( *format == 's' ) {
|
||||||
|
register char *s = (char *)va_arg( args, int );
|
||||||
|
pc += prints (out, s?s:"(null)", width, pad);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( *format == 'd' ) {
|
||||||
|
pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( *format == 'x' ) {
|
||||||
|
pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( *format == 'X' ) {
|
||||||
|
pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( *format == 'u' ) {
|
||||||
|
pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( *format == 'c' ) {
|
||||||
|
/* char are converted to int then pushed on the stack */
|
||||||
|
scr[0] = (char)va_arg( args, int );
|
||||||
|
scr[1] = '\0';
|
||||||
|
pc += prints (out, scr, width, pad);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out:
|
||||||
|
printchar (out, *format);
|
||||||
|
++pc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (out) **out = '\0';
|
||||||
|
va_end( args );
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int printf(const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start( args, format );
|
||||||
|
return print( 0, format, args );
|
||||||
|
}
|
||||||
|
|
||||||
|
int sprintf(char *out, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start( args, format );
|
||||||
|
return print( &out, format, args );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int snprintf( char *buf, unsigned int count, const char *format, ... )
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
( void ) count;
|
||||||
|
|
||||||
|
va_start( args, format );
|
||||||
|
return print( &buf, format, args );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TEST_PRINTF
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
char *ptr = "Hello world!";
|
||||||
|
char *np = 0;
|
||||||
|
int i = 5;
|
||||||
|
unsigned int bs = sizeof(int)*8;
|
||||||
|
int mi;
|
||||||
|
char buf[80];
|
||||||
|
|
||||||
|
mi = (1 << (bs-1)) + 1;
|
||||||
|
printf("%s\n", ptr);
|
||||||
|
printf("printf test\n");
|
||||||
|
printf("%s is null pointer\n", np);
|
||||||
|
printf("%d = 5\n", i);
|
||||||
|
printf("%d = - max int\n", mi);
|
||||||
|
printf("char %c = 'a'\n", 'a');
|
||||||
|
printf("hex %x = ff\n", 0xff);
|
||||||
|
printf("hex %02x = 00\n", 0);
|
||||||
|
printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3);
|
||||||
|
printf("%d %s(s)%", 0, "message");
|
||||||
|
printf("\n");
|
||||||
|
printf("%d %s(s) with %%\n", 0, "message");
|
||||||
|
sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf);
|
||||||
|
sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf);
|
||||||
|
sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf);
|
||||||
|
sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf);
|
||||||
|
sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf);
|
||||||
|
sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf);
|
||||||
|
sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf);
|
||||||
|
sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if you compile this file with
|
||||||
|
* gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c
|
||||||
|
* you will get a normal warning:
|
||||||
|
* printf.c:214: warning: spurious trailing `%' in format
|
||||||
|
* this line is testing an invalid % at the end of the format string.
|
||||||
|
*
|
||||||
|
* this should display (on 32bit int machine) :
|
||||||
|
*
|
||||||
|
* Hello world!
|
||||||
|
* printf test
|
||||||
|
* (null) is null pointer
|
||||||
|
* 5 = 5
|
||||||
|
* -2147483647 = - max int
|
||||||
|
* char a = 'a'
|
||||||
|
* hex ff = ff
|
||||||
|
* hex 00 = 00
|
||||||
|
* signed -3 = unsigned 4294967293 = hex fffffffd
|
||||||
|
* 0 message(s)
|
||||||
|
* 0 message(s) with %
|
||||||
|
* justif: "left "
|
||||||
|
* justif: " right"
|
||||||
|
* 3: 0003 zero padded
|
||||||
|
* 3: 3 left justif.
|
||||||
|
* 3: 3 right justif.
|
||||||
|
* -3: -003 zero padded
|
||||||
|
* -3: -3 left justif.
|
||||||
|
* -3: -3 right justif.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* To keep linker happy. */
|
||||||
|
int write( int i, char* c, int n)
|
||||||
|
{
|
||||||
|
(void)i;
|
||||||
|
(void)n;
|
||||||
|
(void)c;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,268 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Set to 1 to enable functionality */
|
||||||
|
#define __SHOW_KERNEL_PARAMS__ 0
|
||||||
|
|
||||||
|
/* Local definitions boot loader */
|
||||||
|
#define MULTIBOOT_SIGNATURE 0x2BADB002
|
||||||
|
#define MULTIBOOT_BOOTINFO_MMAP 0x00000040
|
||||||
|
|
||||||
|
/* Local definitions for GD table */
|
||||||
|
#define GDT_ENTRIES 8
|
||||||
|
#define GDT_ENTRY_SIZE 8
|
||||||
|
#define GDT_BYTES (GDT_ENTRIES * GDT_ENTRY_SIZE)
|
||||||
|
|
||||||
|
/* Globals and externs */
|
||||||
|
.global _mboot_hdr
|
||||||
|
.global _start
|
||||||
|
.global _restart
|
||||||
|
|
||||||
|
.extern bootsign
|
||||||
|
.extern bootinfo
|
||||||
|
|
||||||
|
.extern __text_start
|
||||||
|
.extern __text_end
|
||||||
|
.extern __data_vma
|
||||||
|
.extern __data_lma
|
||||||
|
.extern __data_start
|
||||||
|
.extern __data_end
|
||||||
|
.extern __bss_start
|
||||||
|
.extern __bss_end
|
||||||
|
.extern __stack_for_main
|
||||||
|
|
||||||
|
.global __text_start
|
||||||
|
.global __text_end
|
||||||
|
.global __data_vma
|
||||||
|
.global __data_lma
|
||||||
|
.global __data_start
|
||||||
|
.global __data_end
|
||||||
|
.global __bss_start
|
||||||
|
.global __bss_end
|
||||||
|
|
||||||
|
.extern setsegs
|
||||||
|
.extern CRT_Init
|
||||||
|
.extern kernel_load_check
|
||||||
|
.extern main
|
||||||
|
|
||||||
|
/* Local constants for multiboot section */
|
||||||
|
.set ALIGN, 1<<0 /* align loaded modules on page boundaries */
|
||||||
|
.set MEMINFO, 1<<1 /* provide memory map */
|
||||||
|
.set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */
|
||||||
|
.set FLAGS, ALIGN|MEMINFO /* this is the multiboot 'flag' field */
|
||||||
|
.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above */
|
||||||
|
|
||||||
|
/* Set-up GDT */
|
||||||
|
.section .data
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
.globl gdt
|
||||||
|
gdt: .space GDT_BYTES
|
||||||
|
gdtr: .word (GDT_BYTES-1) /* sizeof _gdt -1 (in bytes) */
|
||||||
|
.long gdt /* global pointer to the gdt */
|
||||||
|
|
||||||
|
/* Start of application text */
|
||||||
|
.section .text.entry
|
||||||
|
|
||||||
|
/* Skip mb header */
|
||||||
|
jmp _start
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
/* Multiboot header */
|
||||||
|
_mboot_hdr:
|
||||||
|
.long MAGIC /* offset = 0 */
|
||||||
|
.long FLAGS /* offset = 4 */
|
||||||
|
.long CHECKSUM /* offset = 8 */
|
||||||
|
.long _mboot_hdr /* should be header address - offset = 12 */
|
||||||
|
.long __text_start /* load address (start of text) - offset = 16 */
|
||||||
|
.long __bss_start /* load end address (end of data) - offset = 20*/
|
||||||
|
.long __bss_end /* bss end address - offset = 24*/
|
||||||
|
.long _start /* entry_addr - offset = 28*/
|
||||||
|
|
||||||
|
/* Start of executable code */
|
||||||
|
_start:
|
||||||
|
|
||||||
|
/* Store boot arguments */
|
||||||
|
movl %eax, bootsign
|
||||||
|
movl %ebx, bootinfo
|
||||||
|
|
||||||
|
/* Check to see if kernel is bootstrapped by grub */
|
||||||
|
cmpl $MULTIBOOT_SIGNATURE, %eax
|
||||||
|
jne _local_loop
|
||||||
|
testb $MULTIBOOT_BOOTINFO_MMAP, (%ebx)
|
||||||
|
je _local_loop
|
||||||
|
|
||||||
|
_restart:
|
||||||
|
|
||||||
|
/* Initialise the stack pointer */
|
||||||
|
movl $__stack_for_main, %esp
|
||||||
|
|
||||||
|
/* Reset EFLAGS. */
|
||||||
|
pushl $0
|
||||||
|
popf
|
||||||
|
|
||||||
|
/* Set up the global descriptor table */
|
||||||
|
call setsegs
|
||||||
|
lgdt gdtr
|
||||||
|
ljmp $0x8, $gdt1 /* CS descriptor 1 */
|
||||||
|
gdt1:
|
||||||
|
movl $0x10, %eax /* DS descriptor 2 */
|
||||||
|
movw %ax, %ds
|
||||||
|
movw %ax, %es
|
||||||
|
movw %ax, %fs
|
||||||
|
movw %ax, %gs
|
||||||
|
movl $0x18, %eax /* SS descriptor 3 */
|
||||||
|
movw %ax, %ss
|
||||||
|
|
||||||
|
/* Clear interrupt flag */
|
||||||
|
cli
|
||||||
|
|
||||||
|
/* Initialise platform */
|
||||||
|
call CRT_Init
|
||||||
|
|
||||||
|
/* Show kernel parameters and call main, or just call main */
|
||||||
|
#if (__SHOW_KERNEL_PARAMS__ == 1)
|
||||||
|
/*---------------------------------------------------------------------
|
||||||
|
On successful OS load EAX should contain 0x2BADB002
|
||||||
|
EBX should contain the physical address of multiboot info structure
|
||||||
|
|
||||||
|
Push the pointers to the multiboot information structure
|
||||||
|
and the magic number on the stack and check values returned
|
||||||
|
----------------------------------------------------------------------*/
|
||||||
|
movl bootsign, %eax
|
||||||
|
movl bootinfo, %ebx
|
||||||
|
pushl %ebx /* Multiboot information */
|
||||||
|
pushl %eax /* Magic number */
|
||||||
|
call show_kernel_parameters
|
||||||
|
#else
|
||||||
|
/*---------------------------------------------------------------------
|
||||||
|
Call main() routine
|
||||||
|
----------------------------------------------------------------------*/
|
||||||
|
call main
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Should not get here, but just in case - loop forever */
|
||||||
|
cli
|
||||||
|
_local_loop:
|
||||||
|
hlt
|
||||||
|
jmp _local_loop
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
GLOBAL ASSEMBLY LANGUAGE ROUTINES
|
||||||
|
--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* halt */
|
||||||
|
.globl halt
|
||||||
|
halt:
|
||||||
|
jmp halt
|
||||||
|
ret
|
||||||
|
|
||||||
|
/* inb */
|
||||||
|
.globl inb
|
||||||
|
inb: movl 4(%esp), %edx
|
||||||
|
xorl %eax, %eax # clr eax
|
||||||
|
inb %dx, %al
|
||||||
|
ret
|
||||||
|
|
||||||
|
/* inw */
|
||||||
|
.globl inw
|
||||||
|
inw: movl 4(%esp), %edx
|
||||||
|
xorl %eax, %eax # clr eax
|
||||||
|
inw %dx, %ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
/* inl */
|
||||||
|
.globl inl
|
||||||
|
inl: movl 4(%esp), %edx
|
||||||
|
xorl %eax, %eax
|
||||||
|
inl %dx, %eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
/* outb */
|
||||||
|
.globl outb
|
||||||
|
outb: movl 4(%esp), %edx
|
||||||
|
movl 8(%esp), %eax
|
||||||
|
outb %al, %dx
|
||||||
|
ret
|
||||||
|
|
||||||
|
/* outw */
|
||||||
|
.globl outw
|
||||||
|
outw: movl 4(%esp), %edx
|
||||||
|
movl 8(%esp), %eax
|
||||||
|
outw %ax, %dx
|
||||||
|
ret
|
||||||
|
|
||||||
|
/* outl */
|
||||||
|
.globl outl
|
||||||
|
outl: movl 4(%esp), %edx
|
||||||
|
movl 8(%esp), %eax
|
||||||
|
outl %eax, %dx
|
||||||
|
ret
|
||||||
|
|
||||||
|
.end
|
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
#ifndef FREERTOS_STDINT
|
||||||
|
#define FREERTOS_STDINT
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* THIS IS NOT A FULL stdint.h IMPLEMENTATION - It only contains the definitions
|
||||||
|
* necessary to build the FreeRTOS code. It is provided to allow FreeRTOS to be
|
||||||
|
* built using compilers that do not provide their own stdint.h definition.
|
||||||
|
*
|
||||||
|
* To use this file:
|
||||||
|
*
|
||||||
|
* 1) Copy this file into the directory that contains your FreeRTOSConfig.h
|
||||||
|
* header file, as that directory will already be in the compilers include
|
||||||
|
* path.
|
||||||
|
*
|
||||||
|
* 2) Rename the copied file stdint.h.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef signed char int8_t;
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef signed short int16_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef signed long int32_t;
|
||||||
|
typedef unsigned long uint32_t;
|
||||||
|
typedef signed long long int64_t;
|
||||||
|
typedef unsigned long long uint64_t;
|
||||||
|
typedef uint32_t uintn_t;
|
||||||
|
|
||||||
|
#endif /* FREERTOS_STDINT */
|
@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* Temporary file for use only during development when there are no library or
|
||||||
|
* header files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STDIO_H
|
||||||
|
#define STDIO_H
|
||||||
|
|
||||||
|
int sprintf(char *out, const char *format, ...);
|
||||||
|
|
||||||
|
#endif /* stdio_h */
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Temporary file for use only during development when there are no library or
|
||||||
|
* header files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef STDLIB_H
|
||||||
|
#define STDLIB_H
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extremely crude standard library implementations in lieu of having a C
|
||||||
|
* library.
|
||||||
|
*/
|
||||||
|
void *memset( void *pvDest, int iValue, unsigned long ulBytes );
|
||||||
|
void *memcpy( void *pvDest, const void *pvSource, unsigned long ulBytes );
|
||||||
|
int memcmp( const void *pvMem1, const void *pvMem2, unsigned long ulBytes );
|
||||||
|
|
||||||
|
#endif /* STDLIB_H */
|
||||||
|
|
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Temporary file for use only during development when there are no library or
|
||||||
|
* header files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STRING_H
|
||||||
|
#define STRING_H
|
||||||
|
|
||||||
|
//typedef unsigned long size_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extremely crude standard library implementations in lieu of having a C
|
||||||
|
* library.
|
||||||
|
*/
|
||||||
|
unsigned long strlen( const char* pcString );
|
||||||
|
int strcmp( const char *pcString1, const char *pcString2 );
|
||||||
|
void *memset( void *pvDest, int iValue, unsigned long ulBytes );
|
||||||
|
void *memcpy( void *pvDest, const void *pvSource, unsigned long ulBytes );
|
||||||
|
int memcmp( const void *pvMem1, const void *pvMem2, unsigned long ulBytes );
|
||||||
|
#endif /* string_h */
|
@ -0,0 +1,65 @@
|
|||||||
|
OUTPUT_FORMAT("elf32-i386")
|
||||||
|
OUTPUT_ARCH(i386)
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
physbase = 0x00100000;
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = physbase;
|
||||||
|
. = ALIGN(4096);
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
__text_start = ABSOLUTE(.);
|
||||||
|
*(.text.entry)
|
||||||
|
*(.text)
|
||||||
|
*(.text.last)
|
||||||
|
*(.text.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.rodata)
|
||||||
|
*( .rodata.*)
|
||||||
|
__text_end = ABSOLUTE(.);
|
||||||
|
. = ALIGN(4096);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read-write data (initialised) */
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
__data_start = ABSOLUTE(.);
|
||||||
|
__data_lma = LOADADDR(.data);
|
||||||
|
__data_vma = ABSOLUTE(.);
|
||||||
|
*(.data)
|
||||||
|
*(.data.*)
|
||||||
|
__data_end = ABSOLUTE(.);
|
||||||
|
. = ALIGN(4096);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read-write data (uninitialised) */
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
__bss_start = ABSOLUTE(.);
|
||||||
|
*(.bss)
|
||||||
|
*(COMMON)
|
||||||
|
__bss_end = ABSOLUTE(.);
|
||||||
|
. = ALIGN(1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stack used before the scheduler starts */
|
||||||
|
.boot_stack :
|
||||||
|
{
|
||||||
|
/* 2K for the boot stack. This could be avoided by using the same RAM
|
||||||
|
as used by the FreeRTOS system/interrupt stack. */
|
||||||
|
. += 2048;
|
||||||
|
__stack_for_main = ABSOLUTE( . );
|
||||||
|
. = ALIGN(1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*exception unwinding and source language information */
|
||||||
|
.eh_frame : { KEEP (*(.eh_frame)) . = ALIGN(4); }
|
||||||
|
|
||||||
|
/* function exports */
|
||||||
|
.drectve : { KEEP (*(.drectve)) }
|
||||||
|
|
||||||
|
.comment 0 : { *(.comment) }
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,449 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* This project provides two demo applications. A simple blinky style project,
|
||||||
|
* and a more comprehensive test and demo application. The
|
||||||
|
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting (defined in this file) is used to
|
||||||
|
* select between the two. The simply blinky demo is implemented and described
|
||||||
|
* in main_blinky.c. The more comprehensive test and demo application is
|
||||||
|
* implemented and described in main_full.c.
|
||||||
|
*
|
||||||
|
* This file implements the code that is not demo specific, including the
|
||||||
|
* hardware setup and FreeRTOS hook functions.
|
||||||
|
*
|
||||||
|
* ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON
|
||||||
|
* THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO
|
||||||
|
* APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT!
|
||||||
|
* http://www.FreeRTOS.org/RTOS_Intel_Quark_Galileo_GCC.html
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* Standard demo includes, only necessary for the tick hook. */
|
||||||
|
#include "TimerDemo.h"
|
||||||
|
#include "QueueOverwrite.h"
|
||||||
|
#include "EventGroupsDemo.h"
|
||||||
|
#include "QueueSet.h"
|
||||||
|
#include "TaskNotify.h"
|
||||||
|
#include "IntQueue.h"
|
||||||
|
|
||||||
|
/* Added Galileo serial support. */
|
||||||
|
#include "galileo_support.h"
|
||||||
|
|
||||||
|
/* Set to 1 to sit in a loop on start up, allowing a debugger to connect to the
|
||||||
|
application before main() executes. */
|
||||||
|
#define mainWAIT_FOR_DEBUG_CONNECTION 0
|
||||||
|
|
||||||
|
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
|
||||||
|
or 0 to run the more comprehensive test and demo application. */
|
||||||
|
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
|
||||||
|
* main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
|
||||||
|
*/
|
||||||
|
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
|
||||||
|
extern void main_blinky( void );
|
||||||
|
#else
|
||||||
|
extern void main_full( void );
|
||||||
|
#endif /* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
|
||||||
|
|
||||||
|
/* Prototypes for functions called from asm start up code. */
|
||||||
|
int main( void );
|
||||||
|
void CRT_Init( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prototypes for the standard FreeRTOS callback/hook functions implemented
|
||||||
|
* within this file.
|
||||||
|
*/
|
||||||
|
void vApplicationMallocFailedHook( void );
|
||||||
|
void vApplicationIdleHook( void );
|
||||||
|
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
|
||||||
|
void vApplicationTickHook( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform any hardware/peripheral related initialisation necessary to run the
|
||||||
|
* demo.
|
||||||
|
*/
|
||||||
|
static void prvSetupHardware( void );
|
||||||
|
static void prvCalibrateLVTimer( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If mainWAIT_FOR_DEBUG_CONNECTION is set to 1 then the following function will
|
||||||
|
* sit in a loop on start up, allowing a debugger to connect to the application
|
||||||
|
* before main() executes. If mainWAIT_FOR_DEBUG_CONNECTION is not set to 1
|
||||||
|
* then the following function does nothing.
|
||||||
|
*/
|
||||||
|
static void prvLoopToWaitForDebugConnection( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper functions used when an assert is triggered. The first periodically
|
||||||
|
* displays an assert message, and the second clears the assert message when the
|
||||||
|
* function called by the configASSERT() macro is exited.
|
||||||
|
*/
|
||||||
|
static void prvDisplayAssertion( const char * pcFile, unsigned long ulLine );
|
||||||
|
static void prvClearAssertionLine( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* See http://www.FreeRTOS.org/RTOS_Intel_Quark_Galileo_GCC.html for usage
|
||||||
|
instructions. */
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
/* Optionally wait for a debugger to connect. */
|
||||||
|
prvLoopToWaitForDebugConnection();
|
||||||
|
|
||||||
|
/* Init the UART, GPIO, etc. */
|
||||||
|
prvSetupHardware();
|
||||||
|
|
||||||
|
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
|
||||||
|
of this file. */
|
||||||
|
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
|
||||||
|
{
|
||||||
|
g_printf_rcc( 3, 2, DEFAULT_SCREEN_COLOR, "Running main_blinky()." );
|
||||||
|
main_blinky();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
g_printf_rcc( 3, 2, DEFAULT_SCREEN_COLOR, "Running main_full()." );
|
||||||
|
main_full();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vApplicationMallocFailedHook( void )
|
||||||
|
{
|
||||||
|
/* Called if a call to pvPortMalloc() fails because there is insufficient
|
||||||
|
free memory available in the FreeRTOS heap. pvPortMalloc() is called
|
||||||
|
internally by FreeRTOS API functions that create tasks, queues, software
|
||||||
|
timers, and semaphores. The size of the FreeRTOS heap is set by the
|
||||||
|
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h.
|
||||||
|
|
||||||
|
Force an assert. */
|
||||||
|
configASSERT( xTaskGetTickCount() == 0 );
|
||||||
|
taskDISABLE_INTERRUPTS();
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
|
||||||
|
{
|
||||||
|
( void ) pcTaskName;
|
||||||
|
( void ) pxTask;
|
||||||
|
|
||||||
|
/* Run time stack overflow checking is performed if
|
||||||
|
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
|
||||||
|
function is called if a stack overflow is detected.
|
||||||
|
|
||||||
|
Increase the size of the stack allocated to the offending task.
|
||||||
|
|
||||||
|
Force an assert. */
|
||||||
|
configASSERT( pxTask == NULL );
|
||||||
|
taskDISABLE_INTERRUPTS();
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vApplicationIdleHook( void )
|
||||||
|
{
|
||||||
|
volatile unsigned long xFreeHeapSpace;
|
||||||
|
|
||||||
|
/* This is just a trivial example of an idle hook. It is called on each
|
||||||
|
cycle of the idle task. It must *NOT* attempt to block. In this case the
|
||||||
|
idle task just queries the amount of FreeRTOS heap that remains. See the
|
||||||
|
memory management section on the http://www.FreeRTOS.org web site for memory
|
||||||
|
management options. If there is a lot of heap memory free then the
|
||||||
|
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
|
||||||
|
RAM. */
|
||||||
|
xFreeHeapSpace = xPortGetFreeHeapSize();
|
||||||
|
|
||||||
|
/* Remove compiler warning about xFreeHeapSpace being set but never used. */
|
||||||
|
( void ) xFreeHeapSpace;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvDisplayAssertion( const char * pcFile, unsigned long ulLine )
|
||||||
|
{
|
||||||
|
extern void vMilliSecondDelay( uint32_t DelayTime );
|
||||||
|
const uint32_t ul500ms = 500UL;
|
||||||
|
|
||||||
|
/* Display assertion file and line. Don't use the gated g_printf just in
|
||||||
|
the assert was triggered while the gating semaphore was taken. Always print
|
||||||
|
on line 23. */
|
||||||
|
UngatedMoveToScreenPosition( 23, 2 );
|
||||||
|
printf( ANSI_COLOR_RED );
|
||||||
|
printf( "ASSERT: File = %s, Line = %u\n\r", pcFile, ulLine );
|
||||||
|
printf( ANSI_COLOR_RESET );
|
||||||
|
printf( ANSI_SHOW_CURSOR );
|
||||||
|
vMilliSecondDelay( ul500ms );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvClearAssertionLine( void )
|
||||||
|
{
|
||||||
|
UngatedMoveToScreenPosition( 23, 1 );
|
||||||
|
printf( ANSI_COLOR_RESET );
|
||||||
|
printf( ANSI_CLEAR_LINE );
|
||||||
|
printf( ANSI_HIDE_CURSOR );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vAssertCalled( const char * pcFile, unsigned long ulLine )
|
||||||
|
{
|
||||||
|
volatile uint32_t ul = 0;
|
||||||
|
|
||||||
|
( void ) pcFile;
|
||||||
|
( void ) ulLine;
|
||||||
|
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
/* Set ul to a non-zero value or press a key to step out of this
|
||||||
|
function in order to inspect the location of the assert(). */
|
||||||
|
|
||||||
|
/* Clear any pending key presses. */
|
||||||
|
while( ucGalileoGetchar() != 0 )
|
||||||
|
{
|
||||||
|
/* Nothing to do here - the key press is just discarded. */
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
prvDisplayAssertion(pcFile, ulLine);
|
||||||
|
} while ( ( ul == pdFALSE ) && ( ucGalileoGetchar() == 0 ) );
|
||||||
|
|
||||||
|
prvClearAssertionLine();
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vApplicationTickHook( void )
|
||||||
|
{
|
||||||
|
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 )
|
||||||
|
{
|
||||||
|
extern void vTimerPeriodicISRTests( void );
|
||||||
|
|
||||||
|
/* The full demo includes a software timer demo/test that requires
|
||||||
|
prodding periodically from the tick interrupt. */
|
||||||
|
vTimerPeriodicISRTests();
|
||||||
|
|
||||||
|
/* Call the periodic queue overwrite from ISR demo. */
|
||||||
|
vQueueOverwritePeriodicISRDemo();
|
||||||
|
|
||||||
|
/* Call the periodic event group from ISR demo. */
|
||||||
|
vPeriodicEventGroupsProcessing();
|
||||||
|
|
||||||
|
/* Call the periodic queue set from ISR demo. */
|
||||||
|
vQueueSetAccessQueueSetFromISR();
|
||||||
|
|
||||||
|
/* Use task notifications from an interrupt. */
|
||||||
|
xNotifyTaskFromISR();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSetupHardware( void )
|
||||||
|
{
|
||||||
|
ClearScreen();
|
||||||
|
printf( ANSI_COLOR_WHITE );
|
||||||
|
|
||||||
|
/* Initialise the serial port and GPIO. */
|
||||||
|
vInitializeGalileoSerialPort( DEBUG_SERIAL_PORT );
|
||||||
|
vGalileoInitializeGpioController();
|
||||||
|
vGalileoInitializeLegacyGPIO();
|
||||||
|
|
||||||
|
/* Initialise HPET interrupt(s) */
|
||||||
|
#if( ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 ) && ( hpetHPET_TIMER_IN_USE != 0 ) )
|
||||||
|
{
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
vInitializeAllHPETInterrupts();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Setup the LED. */
|
||||||
|
vGalileoLegacyGPIOInitializationForLED();
|
||||||
|
|
||||||
|
/* Demonstrates how to calibrate LAPIC Timer. The calibration value
|
||||||
|
calculated here may get overwritten when the scheduler starts. */
|
||||||
|
prvCalibrateLVTimer();
|
||||||
|
|
||||||
|
/* Print RTOS loaded message. */
|
||||||
|
vPrintBanner();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvLoopToWaitForDebugConnection( void )
|
||||||
|
{
|
||||||
|
/* Debug if define = 1. */
|
||||||
|
#if( mainWAIT_FOR_DEBUG_CONNECTION == 1 )
|
||||||
|
{
|
||||||
|
/* When using the debugger, set this value to pdFALSE, and the application
|
||||||
|
will sit in a loop at the top of main() to allow the debugger to attached
|
||||||
|
before the application starts running. Once attached, set
|
||||||
|
ulExitResetSpinLoop to a non-zero value to leave the loop. */
|
||||||
|
volatile uint32_t ulExitResetSpinLoop = pdFALSE;
|
||||||
|
|
||||||
|
/* Must initialize UART before anything will print. */
|
||||||
|
vInitializeGalileoSerialPort( DEBUG_SERIAL_PORT );
|
||||||
|
|
||||||
|
/* RTOS loaded message. */
|
||||||
|
vPrintBanner();
|
||||||
|
|
||||||
|
/* Output instruction message. */
|
||||||
|
MoveToScreenPosition( 3, 1 );
|
||||||
|
g_printf( DEFAULT_SCREEN_COLOR );
|
||||||
|
g_printf( " Waiting for JTAG connection.\n\n\r" );
|
||||||
|
g_printf( ANSI_COLOR_RESET );
|
||||||
|
g_printf( " Once connected, either set ulExitResetSpinLoop to a non-zero value,\n\r" );
|
||||||
|
g_printf( " or you can [PRESS ANY KEY] to start the debug session.\n\n\r" );
|
||||||
|
printf( ANSI_SHOW_CURSOR );
|
||||||
|
|
||||||
|
/* Use the debugger to set the ulExitResetSpinLoop to a non-zero value
|
||||||
|
or press a key to exit this loop, and step through the application. In
|
||||||
|
Eclipse, simple hover over the variable to see its value in a pop-over
|
||||||
|
box, then edit the value in the pop-over box. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
portNOP();
|
||||||
|
|
||||||
|
} while( ( ulExitResetSpinLoop == pdFALSE ) && ( ucGalileoGetchar() == 0 ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void CRT_Init( void )
|
||||||
|
{
|
||||||
|
extern uint32_t __bss_start[];
|
||||||
|
extern uint32_t __bss_end[];
|
||||||
|
extern uint32_t __data_vma[];
|
||||||
|
extern uint32_t __data_lma[];
|
||||||
|
extern uint32_t __data_start[];
|
||||||
|
extern uint32_t __data_end[];
|
||||||
|
uint32_t x = 255;
|
||||||
|
size_t xSize;
|
||||||
|
|
||||||
|
/* Zero out bss. */
|
||||||
|
xSize = ( ( size_t ) __bss_end ) - ( ( size_t ) __bss_start );
|
||||||
|
memset( ( void * ) __bss_start, 0x00, xSize );
|
||||||
|
|
||||||
|
/* Copy initialised variables. */
|
||||||
|
xSize = ( ( size_t ) __data_end ) - ( ( size_t ) __data_start );
|
||||||
|
memcpy( ( void * ) __data_vma, __data_lma, xSize );
|
||||||
|
|
||||||
|
/* Ensure no interrupts are pending. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
portAPIC_EOI = 0;
|
||||||
|
x--;
|
||||||
|
} while( x > 0 );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCalibrateLVTimer( void )
|
||||||
|
{
|
||||||
|
uint32_t uiInitialTimerCounts, uiCalibratedTimerCounts;
|
||||||
|
|
||||||
|
/* Disable LAPIC Counter. */
|
||||||
|
portAPIC_LVT_TIMER = portAPIC_DISABLE;
|
||||||
|
|
||||||
|
/* Calibrate the LV Timer counts to ensure it matches the HPET timer over
|
||||||
|
extended periods. */
|
||||||
|
uiInitialTimerCounts = ( ( configCPU_CLOCK_HZ >> 4UL ) / configTICK_RATE_HZ );
|
||||||
|
uiCalibratedTimerCounts = uiCalibrateTimer( 0, hpetLVTIMER );
|
||||||
|
|
||||||
|
if( uiCalibratedTimerCounts != 0 )
|
||||||
|
{
|
||||||
|
uiInitialTimerCounts = uiCalibratedTimerCounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the interrupt frequency. */
|
||||||
|
portAPIC_TMRDIV = portAPIC_DIV_16;
|
||||||
|
portAPIC_TIMER_INITIAL_COUNT = uiInitialTimerCounts;
|
||||||
|
|
||||||
|
/* Enable LAPIC Counter. */
|
||||||
|
portAPIC_LVT_TIMER = portAPIC_TIMER_PERIODIC | portAPIC_TIMER_INT_VECTOR;
|
||||||
|
|
||||||
|
/* Sometimes needed. */
|
||||||
|
portAPIC_TMRDIV = portAPIC_DIV_16;
|
||||||
|
}
|
@ -0,0 +1,169 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
.extern ulTopOfSystemStack
|
||||||
|
.extern ulInterruptNesting
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
.macro portFREERTOS_INTERRUPT_ENTRY
|
||||||
|
|
||||||
|
/* Save general purpose registers. */
|
||||||
|
pusha
|
||||||
|
|
||||||
|
/* If ulInterruptNesting is zero the rest of the task context will need
|
||||||
|
saving and a stack switch might be required. */
|
||||||
|
movl ulInterruptNesting, %eax
|
||||||
|
test %eax, %eax
|
||||||
|
jne 2f
|
||||||
|
|
||||||
|
/* Interrupts are not nested, so save the rest of the task context. */
|
||||||
|
.if configSUPPORT_FPU == 1
|
||||||
|
|
||||||
|
/* If the task has a buffer allocated to save the FPU context then
|
||||||
|
save the FPU context now. */
|
||||||
|
movl pucPortTaskFPUContextBuffer, %eax
|
||||||
|
test %eax, %eax
|
||||||
|
je 1f
|
||||||
|
fnsave ( %eax ) /* Save FLOP context into ucTempFPUBuffer array. */
|
||||||
|
fwait
|
||||||
|
|
||||||
|
1:
|
||||||
|
/* Save the address of the FPU context, if any. */
|
||||||
|
push pucPortTaskFPUContextBuffer
|
||||||
|
|
||||||
|
.endif /* configSUPPORT_FPU */
|
||||||
|
|
||||||
|
/* Find the TCB. */
|
||||||
|
movl pxCurrentTCB, %eax
|
||||||
|
|
||||||
|
/* Stack location is first item in the TCB. */
|
||||||
|
movl %esp, (%eax)
|
||||||
|
|
||||||
|
/* Switch stacks. */
|
||||||
|
movl ulTopOfSystemStack, %esp
|
||||||
|
movl %esp, %ebp
|
||||||
|
|
||||||
|
2:
|
||||||
|
/* Increment nesting count. */
|
||||||
|
add $1, ulInterruptNesting
|
||||||
|
|
||||||
|
.endm
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
.macro portINTERRUPT_EPILOGUE
|
||||||
|
|
||||||
|
cli
|
||||||
|
sub $1, ulInterruptNesting
|
||||||
|
|
||||||
|
/* If the nesting has unwound to zero. */
|
||||||
|
movl ulInterruptNesting, %eax
|
||||||
|
test %eax, %eax
|
||||||
|
jne 2f
|
||||||
|
|
||||||
|
/* If a yield was requested then select a new TCB now. */
|
||||||
|
movl ulPortYieldPending, %eax
|
||||||
|
test %eax, %eax
|
||||||
|
je 1f
|
||||||
|
movl $0, ulPortYieldPending
|
||||||
|
call vTaskSwitchContext
|
||||||
|
|
||||||
|
1:
|
||||||
|
/* Stack location is first item in the TCB. */
|
||||||
|
movl pxCurrentTCB, %eax
|
||||||
|
movl (%eax), %esp
|
||||||
|
|
||||||
|
.if configSUPPORT_FPU == 1
|
||||||
|
|
||||||
|
/* Restore address of task's FPU context buffer. */
|
||||||
|
pop pucPortTaskFPUContextBuffer
|
||||||
|
|
||||||
|
/* If the task has a buffer allocated in which its FPU context is saved,
|
||||||
|
then restore it now. */
|
||||||
|
movl pucPortTaskFPUContextBuffer, %eax
|
||||||
|
test %eax, %eax
|
||||||
|
je 1f
|
||||||
|
frstor ( %eax )
|
||||||
|
1:
|
||||||
|
.endif
|
||||||
|
|
||||||
|
2:
|
||||||
|
popa
|
||||||
|
|
||||||
|
.endm
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
.macro portFREERTOS_INTERRUPT_EXIT
|
||||||
|
|
||||||
|
portINTERRUPT_EPILOGUE
|
||||||
|
/* EOI. */
|
||||||
|
movl $0x00, (0xFEE000B0)
|
||||||
|
iret
|
||||||
|
|
||||||
|
.endm
|
@ -0,0 +1,724 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||||
|
/* Check the configuration. */
|
||||||
|
#if( configMAX_PRIORITIES > 32 )
|
||||||
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
|
#endif
|
||||||
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
#if( configISR_STACK_SIZE < ( configMINIMAL_STACK_SIZE * 2 ) )
|
||||||
|
#warning configISR_STACK_SIZE is probably too small!
|
||||||
|
#endif /* ( configISR_STACK_SIZE < configMINIMAL_STACK_SIZE * 2 ) */
|
||||||
|
|
||||||
|
#if( ( configMAX_API_CALL_INTERRUPT_PRIORITY > portMAX_PRIORITY ) || ( configMAX_API_CALL_INTERRUPT_PRIORITY < 2 ) )
|
||||||
|
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be between 2 and 15
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* A critical section is exited when the critical section nesting count reaches
|
||||||
|
this value. */
|
||||||
|
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||||
|
|
||||||
|
/* Tasks are not created with a floating point context, but can be given a
|
||||||
|
floating point context after they have been created. A variable is stored as
|
||||||
|
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||||
|
does not have an FPU context, or any other value if the task does have an FPU
|
||||||
|
context. */
|
||||||
|
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||||
|
|
||||||
|
/* Only the IF bit is set so tasks start with interrupts enabled. */
|
||||||
|
#define portINITIAL_EFLAGS ( 0x200UL )
|
||||||
|
|
||||||
|
/* Error interrupts are at the highest priority vectors. */
|
||||||
|
#define portAPIC_LVT_ERROR_VECTOR ( 0xfe )
|
||||||
|
#define portAPIC_SPURIOUS_INT_VECTOR ( 0xff )
|
||||||
|
|
||||||
|
/* EFLAGS bits. */
|
||||||
|
#define portEFLAGS_IF ( 0x200UL )
|
||||||
|
|
||||||
|
/* FPU context size if FSAVE is used. */
|
||||||
|
#define portFPU_CONTEXT_SIZE_BYTES 108
|
||||||
|
|
||||||
|
/* The expected size of each entry in the IDT. Used to check structure packing
|
||||||
|
is set correctly. */
|
||||||
|
#define portEXPECTED_IDT_ENTRY_SIZE 8
|
||||||
|
|
||||||
|
/* Default flags setting for entries in the IDT. */
|
||||||
|
#define portIDT_FLAGS ( 0x8E )
|
||||||
|
|
||||||
|
/* This is the lowest possible ISR vector available to application code. */
|
||||||
|
#define portAPIC_MIN_ALLOWABLE_VECTOR ( 0x20 )
|
||||||
|
|
||||||
|
/* If configASSERT() is defined then the system stack is filled with this value
|
||||||
|
to allow for a crude stack overflow check. */
|
||||||
|
#define portSTACK_WORD ( 0xecececec )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Starts the first task executing.
|
||||||
|
*/
|
||||||
|
extern void vPortStartFirstTask( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used to catch tasks that attempt to return from their implementing function.
|
||||||
|
*/
|
||||||
|
static void prvTaskExitError( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Complete one descriptor in the IDT.
|
||||||
|
*/
|
||||||
|
static void prvSetInterruptGate( uint8_t ucNumber, ISR_Handler_t pxHandlerFunction, uint8_t ucFlags );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The default handler installed in each IDT position.
|
||||||
|
*/
|
||||||
|
extern void vPortCentralInterruptWrapper( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handler for portYIELD().
|
||||||
|
*/
|
||||||
|
extern void vPortYieldCall( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure the APIC to generate the RTOS tick.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tick interrupt handler.
|
||||||
|
*/
|
||||||
|
extern void vPortTimerHandler( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check an interrupt vector is not too high, too low, in use by FreeRTOS, or
|
||||||
|
* already in use by the application.
|
||||||
|
*/
|
||||||
|
static BaseType_t prvCheckValidityOfVectorNumber( uint32_t ulVectorNumber );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* A variable is used to keep track of the critical section nesting. This
|
||||||
|
variable must be initialised to a non zero value to ensure interrupts don't
|
||||||
|
inadvertently become unmasked before the scheduler starts. It is set to zero
|
||||||
|
before the first task starts executing. */
|
||||||
|
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
|
/* A structure used to map the various fields of an IDT entry into separate
|
||||||
|
structure members. */
|
||||||
|
struct IDTEntry
|
||||||
|
{
|
||||||
|
uint16_t usISRLow; /* Low 16 bits of handler address. */
|
||||||
|
uint16_t usSegmentSelector; /* Flat model means this is not changed. */
|
||||||
|
uint8_t ucZero; /* Must be set to zero. */
|
||||||
|
uint8_t ucFlags; /* Flags for this entry. */
|
||||||
|
uint16_t usISRHigh; /* High 16 bits of handler address. */
|
||||||
|
} __attribute__( ( packed ) );
|
||||||
|
typedef struct IDTEntry IDTEntry_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* Use to pass the location of the IDT to the CPU. */
|
||||||
|
struct IDTPointer
|
||||||
|
{
|
||||||
|
uint16_t usTableLimit;
|
||||||
|
uint32_t ulTableBase; /* The address of the first entry in xInterruptDescriptorTable. */
|
||||||
|
} __attribute__( ( __packed__ ) );
|
||||||
|
typedef struct IDTPointer IDTPointer_t;
|
||||||
|
|
||||||
|
/* The IDT itself. */
|
||||||
|
static __attribute__ ( ( aligned( 32 ) ) ) IDTEntry_t xInterruptDescriptorTable[ portNUM_VECTORS ];
|
||||||
|
|
||||||
|
#if ( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 )
|
||||||
|
|
||||||
|
/* A table in which application defined interrupt handlers are stored. These
|
||||||
|
are called by the central interrupt handler if a common interrupt entry
|
||||||
|
point it used. */
|
||||||
|
static ISR_Handler_t xInterruptHandlerTable[ portNUM_VECTORS ] = { NULL };
|
||||||
|
|
||||||
|
#endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */
|
||||||
|
|
||||||
|
#if ( configSUPPORT_FPU == 1 )
|
||||||
|
|
||||||
|
/* Saved as part of the task context. If pucPortTaskFPUContextBuffer is NULL
|
||||||
|
then the task does not have an FPU context. If pucPortTaskFPUContextBuffer is
|
||||||
|
not NULL then it points to a buffer into which the FPU context can be saved. */
|
||||||
|
uint8_t *pucPortTaskFPUContextBuffer __attribute__((used)) = pdFALSE;
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_FPU */
|
||||||
|
|
||||||
|
/* The stack used by interrupt handlers. */
|
||||||
|
static uint32_t ulSystemStack[ configISR_STACK_SIZE ] __attribute__((used)) = { 0 };
|
||||||
|
|
||||||
|
/* Don't use the very top of the system stack so the return address
|
||||||
|
appears as 0 if the debugger tries to unwind the stack. */
|
||||||
|
volatile uint32_t ulTopOfSystemStack __attribute__((used)) = ( uint32_t ) &( ulSystemStack[ configISR_STACK_SIZE - 5 ] );
|
||||||
|
|
||||||
|
/* If a yield is requested from an interrupt or from a critical section then
|
||||||
|
the yield is not performed immediately, and ulPortYieldPending is set to pdTRUE
|
||||||
|
instead to indicate the yield should be performed at the end of the interrupt
|
||||||
|
when the critical section is exited. */
|
||||||
|
volatile uint32_t ulPortYieldPending __attribute__((used)) = pdFALSE;
|
||||||
|
|
||||||
|
/* Counts the interrupt nesting depth. Used to know when to switch to the
|
||||||
|
interrupt/system stack and when to save/restore a complete context. */
|
||||||
|
volatile uint32_t ulInterruptNesting __attribute__((used)) = 0;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
uint32_t ulCodeSegment;
|
||||||
|
|
||||||
|
/* Setup the initial stack as expected by the portFREERTOS_INTERRUPT_EXIT macro. */
|
||||||
|
|
||||||
|
*pxTopOfStack = 0x00;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x00;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Parameters first. */
|
||||||
|
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* There is nothing to return to so assert if attempting to use the return
|
||||||
|
address. */
|
||||||
|
*pxTopOfStack = ( StackType_t ) prvTaskExitError;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* iret used to start the task pops up to here. */
|
||||||
|
*pxTopOfStack = portINITIAL_EFLAGS;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* CS */
|
||||||
|
__asm volatile( "movl %%cs, %0" : "=r" ( ulCodeSegment ) );
|
||||||
|
*pxTopOfStack = ulCodeSegment;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* First instruction in the task. */
|
||||||
|
*pxTopOfStack = ( StackType_t ) pxCode;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* General purpose registers as expected by a POPA instruction. */
|
||||||
|
*pxTopOfStack = 0xEA;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = 0xEC;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = 0xED1; /* EDX */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = 0xEB1; /* EBX */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Hole for ESP. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = 0x00; /* EBP */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = 0xE5; /* ESI */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = 0xeeeeeeee; /* EDI */
|
||||||
|
|
||||||
|
#if ( configSUPPORT_FPU == 1 )
|
||||||
|
{
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Buffer for FPU context, which is initialised to NULL as tasks are not
|
||||||
|
created with an FPU context. */
|
||||||
|
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_FPU */
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSetInterruptGate( uint8_t ucNumber, ISR_Handler_t pxHandlerFunction, uint8_t ucFlags )
|
||||||
|
{
|
||||||
|
uint16_t usCodeSegment;
|
||||||
|
uint32_t ulBase = ( uint32_t ) pxHandlerFunction;
|
||||||
|
|
||||||
|
xInterruptDescriptorTable[ ucNumber ].usISRLow = ( uint16_t ) ( ulBase & USHRT_MAX );
|
||||||
|
xInterruptDescriptorTable[ ucNumber ].usISRHigh = ( uint16_t ) ( ( ulBase >> 16UL ) & USHRT_MAX );
|
||||||
|
|
||||||
|
/* When the flat model is used the CS will never change. */
|
||||||
|
__asm volatile( "mov %%cs, %0" : "=r" ( usCodeSegment ) );
|
||||||
|
xInterruptDescriptorTable[ ucNumber ].usSegmentSelector = usCodeSegment;
|
||||||
|
xInterruptDescriptorTable[ ucNumber ].ucZero = 0;
|
||||||
|
xInterruptDescriptorTable[ ucNumber ].ucFlags = ucFlags;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortSetupIDT( void )
|
||||||
|
{
|
||||||
|
uint32_t ulNum;
|
||||||
|
IDTPointer_t xIDT;
|
||||||
|
|
||||||
|
#if ( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 )
|
||||||
|
{
|
||||||
|
for( ulNum = 0; ulNum < portNUM_VECTORS; ulNum++ )
|
||||||
|
{
|
||||||
|
/* If a handler has not already been installed on this vector. */
|
||||||
|
if( ( xInterruptDescriptorTable[ ulNum ].usISRLow == 0x00 ) && ( xInterruptDescriptorTable[ ulNum ].usISRHigh == 0x00 ) )
|
||||||
|
{
|
||||||
|
prvSetInterruptGate( ( uint8_t ) ulNum, vPortCentralInterruptWrapper, portIDT_FLAGS );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */
|
||||||
|
|
||||||
|
/* Set IDT address. */
|
||||||
|
xIDT.ulTableBase = ( uint32_t ) xInterruptDescriptorTable;
|
||||||
|
xIDT.usTableLimit = sizeof( xInterruptDescriptorTable ) - 1;
|
||||||
|
|
||||||
|
/* Set IDT in CPU. */
|
||||||
|
__asm volatile( "lidt %0" :: "m" (xIDT) );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvTaskExitError( void )
|
||||||
|
{
|
||||||
|
/* A function that implements a task must not exit or attempt to return to
|
||||||
|
its caller as there is nothing to return to. If a task wants to exit it
|
||||||
|
should instead call vTaskDelete( NULL ).
|
||||||
|
|
||||||
|
Artificially force an assert() to be triggered if configASSERT() is
|
||||||
|
defined, then stop here so application writers can catch the error. */
|
||||||
|
configASSERT( ulCriticalNesting == ~0UL );
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
extern void vPortAPICErrorHandlerWrapper( void );
|
||||||
|
extern void vPortAPICSpuriousHandler( void );
|
||||||
|
|
||||||
|
/* Initialise LAPIC to a well known state. */
|
||||||
|
portAPIC_LDR = 0xFFFFFFFF;
|
||||||
|
portAPIC_LDR = ( ( portAPIC_LDR & 0x00FFFFFF ) | 0x00000001 );
|
||||||
|
portAPIC_LVT_TIMER = portAPIC_DISABLE;
|
||||||
|
portAPIC_LVT_PERF = portAPIC_NMI;
|
||||||
|
portAPIC_LVT_LINT0 = portAPIC_DISABLE;
|
||||||
|
portAPIC_LVT_LINT1 = portAPIC_DISABLE;
|
||||||
|
portAPIC_TASK_PRIORITY = 0;
|
||||||
|
|
||||||
|
/* Install APIC timer ISR vector. */
|
||||||
|
prvSetInterruptGate( ( uint8_t ) portAPIC_TIMER_INT_VECTOR, vPortTimerHandler, portIDT_FLAGS );
|
||||||
|
|
||||||
|
/* Install API error handler. */
|
||||||
|
prvSetInterruptGate( ( uint8_t ) portAPIC_LVT_ERROR_VECTOR, vPortAPICErrorHandlerWrapper, portIDT_FLAGS );
|
||||||
|
|
||||||
|
/* Install Yield handler. */
|
||||||
|
prvSetInterruptGate( ( uint8_t ) portAPIC_YIELD_INT_VECTOR, vPortYieldCall, portIDT_FLAGS );
|
||||||
|
|
||||||
|
/* Install spurious interrupt vector. */
|
||||||
|
prvSetInterruptGate( ( uint8_t ) portAPIC_SPURIOUS_INT_VECTOR, vPortAPICSpuriousHandler, portIDT_FLAGS );
|
||||||
|
|
||||||
|
/* Enable the APIC, mapping the spurious interrupt at the same time. */
|
||||||
|
portAPIC_SPURIOUS_INT = portAPIC_SPURIOUS_INT_VECTOR | portAPIC_ENABLE_BIT;
|
||||||
|
|
||||||
|
/* Set timer error vector. */
|
||||||
|
portAPIC_LVT_ERROR = portAPIC_LVT_ERROR_VECTOR;
|
||||||
|
|
||||||
|
/* Set the interrupt frequency. */
|
||||||
|
portAPIC_TMRDIV = portAPIC_DIV_16;
|
||||||
|
portAPIC_TIMER_INITIAL_COUNT = ( ( configCPU_CLOCK_HZ >> 4UL ) / configTICK_RATE_HZ ) - 1UL;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
BaseType_t xWord;
|
||||||
|
|
||||||
|
/* Some versions of GCC require the -mno-ms-bitfields command line option
|
||||||
|
for packing to work. */
|
||||||
|
configASSERT( sizeof( struct IDTEntry ) == portEXPECTED_IDT_ENTRY_SIZE );
|
||||||
|
|
||||||
|
/* Fill part of the system stack with a known value to help detect stack
|
||||||
|
overflow. A few zeros are left so GDB doesn't get confused unwinding
|
||||||
|
the stack. */
|
||||||
|
for( xWord = 0; xWord < configISR_STACK_SIZE - 20; xWord++ )
|
||||||
|
{
|
||||||
|
ulSystemStack[ xWord ] = portSTACK_WORD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialise Interrupt Descriptor Table (IDT). */
|
||||||
|
vPortSetupIDT();
|
||||||
|
|
||||||
|
/* Initialise LAPIC and install system handlers. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Make sure the stack used by interrupts is aligned. */
|
||||||
|
ulTopOfSystemStack &= ~portBYTE_ALIGNMENT_MASK;
|
||||||
|
|
||||||
|
ulCriticalNesting = 0;
|
||||||
|
|
||||||
|
/* Enable LAPIC Counter.*/
|
||||||
|
portAPIC_LVT_TIMER = portAPIC_TIMER_PERIODIC | portAPIC_TIMER_INT_VECTOR;
|
||||||
|
|
||||||
|
/* Sometimes needed. */
|
||||||
|
portAPIC_TMRDIV = portAPIC_DIV_16;
|
||||||
|
|
||||||
|
/* Should not return from the following function as the scheduler will then
|
||||||
|
be executing the tasks. */
|
||||||
|
vPortStartFirstTask();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
|
Artificially force an assert. */
|
||||||
|
configASSERT( ulCriticalNesting == 1000UL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEnterCritical( void )
|
||||||
|
{
|
||||||
|
if( ulCriticalNesting == 0 )
|
||||||
|
{
|
||||||
|
#if( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
||||||
|
{
|
||||||
|
__asm volatile( "cli" );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
portAPIC_TASK_PRIORITY = portMAX_API_CALL_PRIORITY;
|
||||||
|
configASSERT( portAPIC_TASK_PRIORITY == portMAX_API_CALL_PRIORITY );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
|
portENTER_CRITICAL() has been called. */
|
||||||
|
ulCriticalNesting++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortExitCritical( void )
|
||||||
|
{
|
||||||
|
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
|
{
|
||||||
|
/* Decrement the nesting count as the critical section is being
|
||||||
|
exited. */
|
||||||
|
ulCriticalNesting--;
|
||||||
|
|
||||||
|
/* If the nesting level has reached zero then all interrupt
|
||||||
|
priorities must be re-enabled. */
|
||||||
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
|
{
|
||||||
|
/* Critical nesting has reached zero so all interrupt priorities
|
||||||
|
should be unmasked. */
|
||||||
|
#if( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
||||||
|
{
|
||||||
|
__asm volatile( "sti" );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
portAPIC_TASK_PRIORITY = 0;
|
||||||
|
|
||||||
|
/* If a yield was pended from within the critical section then
|
||||||
|
perform the yield now. */
|
||||||
|
if( ulPortYieldPending != pdFALSE )
|
||||||
|
{
|
||||||
|
ulPortYieldPending = pdFALSE;
|
||||||
|
__asm volatile( portYIELD_INTERRUPT );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
uint32_t ulPortSetInterruptMask( void )
|
||||||
|
{
|
||||||
|
volatile uint32_t ulOriginalMask;
|
||||||
|
|
||||||
|
/* Set mask to max syscall priority. */
|
||||||
|
#if( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
||||||
|
{
|
||||||
|
/* Return whether interrupts were already enabled or not. Pop adjusts
|
||||||
|
the stack first. */
|
||||||
|
__asm volatile( "pushf \t\n"
|
||||||
|
"pop %0 \t\n"
|
||||||
|
"cli "
|
||||||
|
: "=rm" (ulOriginalMask) :: "memory" );
|
||||||
|
|
||||||
|
ulOriginalMask &= portEFLAGS_IF;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
/* Return original mask. */
|
||||||
|
ulOriginalMask = portAPIC_TASK_PRIORITY;
|
||||||
|
portAPIC_TASK_PRIORITY = portMAX_API_CALL_PRIORITY;
|
||||||
|
configASSERT( portAPIC_TASK_PRIORITY == portMAX_API_CALL_PRIORITY );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ulOriginalMask;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortClearInterruptMask( uint32_t ulNewMaskValue )
|
||||||
|
{
|
||||||
|
#if( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
||||||
|
{
|
||||||
|
if( ulNewMaskValue != pdFALSE )
|
||||||
|
{
|
||||||
|
__asm volatile( "sti" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
portAPIC_TASK_PRIORITY = ulNewMaskValue;
|
||||||
|
configASSERT( portAPIC_TASK_PRIORITY == ulNewMaskValue );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configSUPPORT_FPU == 1 )
|
||||||
|
|
||||||
|
void vPortTaskUsesFPU( void )
|
||||||
|
{
|
||||||
|
/* A task is registering the fact that it needs an FPU context. Allocate a
|
||||||
|
buffer into which the context can be saved. */
|
||||||
|
pucPortTaskFPUContextBuffer = ( uint8_t * ) pvPortMalloc( portFPU_CONTEXT_SIZE_BYTES );
|
||||||
|
configASSERT( pucPortTaskFPUContextBuffer );
|
||||||
|
|
||||||
|
/* Initialise the floating point registers. */
|
||||||
|
__asm volatile( "fninit" );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_FPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortAPICErrorHandler( void )
|
||||||
|
{
|
||||||
|
/* Variable to hold the APIC error status for viewing in the debugger. */
|
||||||
|
volatile uint32_t ulErrorStatus = 0;
|
||||||
|
|
||||||
|
portAPIC_ERROR_STATUS = 0;
|
||||||
|
ulErrorStatus = portAPIC_ERROR_STATUS;
|
||||||
|
( void ) ulErrorStatus;
|
||||||
|
|
||||||
|
/* Force an assert. */
|
||||||
|
configASSERT( ulCriticalNesting == ~0UL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 )
|
||||||
|
|
||||||
|
void vPortCentralInterruptHandler( uint32_t ulVector )
|
||||||
|
{
|
||||||
|
if( ulVector < portNUM_VECTORS )
|
||||||
|
{
|
||||||
|
if( xInterruptHandlerTable[ ulVector ] != NULL )
|
||||||
|
{
|
||||||
|
( xInterruptHandlerTable[ ulVector ] )();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for a system stack overflow. */
|
||||||
|
configASSERT( ulSystemStack[ 10 ] == portSTACK_WORD );
|
||||||
|
configASSERT( ulSystemStack[ 12 ] == portSTACK_WORD );
|
||||||
|
configASSERT( ulSystemStack[ 14 ] == portSTACK_WORD );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 )
|
||||||
|
|
||||||
|
BaseType_t xPortRegisterCInterruptHandler( ISR_Handler_t pxHandler, uint32_t ulVectorNumber )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
if( prvCheckValidityOfVectorNumber( ulVectorNumber ) != pdFAIL )
|
||||||
|
{
|
||||||
|
/* Save the handler passed in by the application in the vector number
|
||||||
|
passed in. The addresses are then called from the central interrupt
|
||||||
|
handler. */
|
||||||
|
xInterruptHandlerTable[ ulVectorNumber ] = pxHandler;
|
||||||
|
|
||||||
|
xReturn = pdPASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xPortInstallInterruptHandler( ISR_Handler_t pxHandler, uint32_t ulVectorNumber )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
if( prvCheckValidityOfVectorNumber( ulVectorNumber ) != pdFAIL )
|
||||||
|
{
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
/* Update the IDT to include the application defined handler. */
|
||||||
|
prvSetInterruptGate( ( uint8_t ) ulVectorNumber, ( ISR_Handler_t ) pxHandler, portIDT_FLAGS );
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
xReturn = pdPASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static BaseType_t prvCheckValidityOfVectorNumber( uint32_t ulVectorNumber )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
/* Check validity of vector number. */
|
||||||
|
if( ulVectorNumber >= portNUM_VECTORS )
|
||||||
|
{
|
||||||
|
/* Too high. */
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
else if( ulVectorNumber < portAPIC_MIN_ALLOWABLE_VECTOR )
|
||||||
|
{
|
||||||
|
/* Too low. */
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
else if( ulVectorNumber == portAPIC_TIMER_INT_VECTOR )
|
||||||
|
{
|
||||||
|
/* In use by FreeRTOS. */
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
else if( ulVectorNumber == portAPIC_YIELD_INT_VECTOR )
|
||||||
|
{
|
||||||
|
/* In use by FreeRTOS. */
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
else if( ulVectorNumber == portAPIC_LVT_ERROR_VECTOR )
|
||||||
|
{
|
||||||
|
/* In use by FreeRTOS. */
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
else if( ulVectorNumber == portAPIC_SPURIOUS_INT_VECTOR )
|
||||||
|
{
|
||||||
|
/* In use by FreeRTOS. */
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
else if( xInterruptHandlerTable[ ulVectorNumber ] != NULL )
|
||||||
|
{
|
||||||
|
/* Already in use by the application. */
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdPASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vGenerateYieldInterrupt( void )
|
||||||
|
{
|
||||||
|
__asm volatile( portYIELD_INTERRUPT );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,316 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
.file "portASM.S"
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
#include "ISR_Support.h"
|
||||||
|
|
||||||
|
.extern pxCurrentTCB
|
||||||
|
.extern vTaskSwitchContext
|
||||||
|
.extern vPortCentralInterruptHandler
|
||||||
|
.extern xTaskIncrementTick
|
||||||
|
.extern vPortAPICErrorHandler
|
||||||
|
.extern pucPortTaskFPUContextBuffer
|
||||||
|
.extern ulPortYieldPending
|
||||||
|
|
||||||
|
.global vPortStartFirstTask
|
||||||
|
.global vPortCentralInterruptWrapper
|
||||||
|
.global vPortAPICErrorHandlerWrapper
|
||||||
|
.global vPortTimerHandler
|
||||||
|
.global vPortYieldCall
|
||||||
|
.global vPortAPICSpuriousHandler
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
.func vPortYieldCall
|
||||||
|
vPortYieldCall:
|
||||||
|
/* Save general purpose registers. */
|
||||||
|
pusha
|
||||||
|
|
||||||
|
.if configSUPPORT_FPU == 1
|
||||||
|
|
||||||
|
/* If the task has a buffer allocated to save the FPU context then save
|
||||||
|
the FPU context now. */
|
||||||
|
movl pucPortTaskFPUContextBuffer, %eax
|
||||||
|
test %eax, %eax
|
||||||
|
je 1f
|
||||||
|
fnsave ( %eax )
|
||||||
|
fwait
|
||||||
|
|
||||||
|
1:
|
||||||
|
|
||||||
|
/* Save the address of the FPU context, if any. */
|
||||||
|
push pucPortTaskFPUContextBuffer
|
||||||
|
|
||||||
|
.endif /* configSUPPORT_FPU */
|
||||||
|
|
||||||
|
/* Find the TCB. */
|
||||||
|
movl pxCurrentTCB, %eax
|
||||||
|
|
||||||
|
/* Stack location is first item in the TCB. */
|
||||||
|
movl %esp, (%eax)
|
||||||
|
|
||||||
|
call vTaskSwitchContext
|
||||||
|
|
||||||
|
/* Find the location of pxCurrentTCB again - a callee saved register could
|
||||||
|
be used in place of eax to prevent this second load, but that then relies
|
||||||
|
on the compiler and other asm code. */
|
||||||
|
movl pxCurrentTCB, %eax
|
||||||
|
movl (%eax), %esp
|
||||||
|
|
||||||
|
.if configSUPPORT_FPU == 1
|
||||||
|
|
||||||
|
/* Restore address of task's FPU context buffer. */
|
||||||
|
pop pucPortTaskFPUContextBuffer
|
||||||
|
|
||||||
|
/* If the task has a buffer allocated in which its FPU context is saved,
|
||||||
|
then restore it now. */
|
||||||
|
movl pucPortTaskFPUContextBuffer, %eax
|
||||||
|
test %eax, %eax
|
||||||
|
je 1f
|
||||||
|
frstor ( %eax )
|
||||||
|
1:
|
||||||
|
.endif
|
||||||
|
|
||||||
|
popa
|
||||||
|
iret
|
||||||
|
|
||||||
|
.endfunc
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
.func vPortStartFirstTask
|
||||||
|
vPortStartFirstTask:
|
||||||
|
|
||||||
|
/* Find the TCB. */
|
||||||
|
movl pxCurrentTCB, %eax
|
||||||
|
|
||||||
|
/* Stack location is first item in the TCB. */
|
||||||
|
movl (%eax), %esp
|
||||||
|
|
||||||
|
/* Restore FPU context flag. */
|
||||||
|
.if configSUPPORT_FPU == 1
|
||||||
|
|
||||||
|
pop pucPortTaskFPUContextBuffer
|
||||||
|
|
||||||
|
.endif /* configSUPPORT_FPU */
|
||||||
|
|
||||||
|
/* Restore general purpose registers. */
|
||||||
|
popa
|
||||||
|
iret
|
||||||
|
.endfunc
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
.func vPortAPICErrorHandlerWrapper
|
||||||
|
vPortAPICErrorHandlerWrapper:
|
||||||
|
pusha
|
||||||
|
call vPortAPICErrorHandler
|
||||||
|
popa
|
||||||
|
/* EOI. */
|
||||||
|
movl $0x00, (0xFEE000B0)
|
||||||
|
iret
|
||||||
|
.endfunc
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
.func vPortTimerHandler
|
||||||
|
vPortTimerHandler:
|
||||||
|
|
||||||
|
/* Save general purpose registers. */
|
||||||
|
pusha
|
||||||
|
|
||||||
|
/* Interrupts are not nested, so save the rest of the task context. */
|
||||||
|
.if configSUPPORT_FPU == 1
|
||||||
|
|
||||||
|
/* If the task has a buffer allocated to save the FPU context then save the
|
||||||
|
FPU context now. */
|
||||||
|
movl pucPortTaskFPUContextBuffer, %eax
|
||||||
|
test %eax, %eax
|
||||||
|
je 1f
|
||||||
|
fnsave ( %eax ) /* Save FLOP context into ucTempFPUBuffer array. */
|
||||||
|
fwait
|
||||||
|
|
||||||
|
1:
|
||||||
|
/* Save the address of the FPU context, if any. */
|
||||||
|
push pucPortTaskFPUContextBuffer
|
||||||
|
|
||||||
|
.endif /* configSUPPORT_FPU */
|
||||||
|
|
||||||
|
/* Find the TCB. */
|
||||||
|
movl pxCurrentTCB, %eax
|
||||||
|
|
||||||
|
/* Stack location is first item in the TCB. */
|
||||||
|
movl %esp, (%eax)
|
||||||
|
|
||||||
|
/* Switch stacks. */
|
||||||
|
movl ulTopOfSystemStack, %esp
|
||||||
|
movl %esp, %ebp
|
||||||
|
|
||||||
|
/* Increment nesting count. */
|
||||||
|
add $1, ulInterruptNesting
|
||||||
|
|
||||||
|
call xTaskIncrementTick
|
||||||
|
|
||||||
|
sti
|
||||||
|
|
||||||
|
/* Is a switch to another task required? */
|
||||||
|
test %eax, %eax
|
||||||
|
je _skip_context_switch
|
||||||
|
cli
|
||||||
|
call vTaskSwitchContext
|
||||||
|
|
||||||
|
_skip_context_switch:
|
||||||
|
cli
|
||||||
|
|
||||||
|
/* Decrement the variable used to determine if a switch to a system
|
||||||
|
stack is necessary. */
|
||||||
|
sub $1, ulInterruptNesting
|
||||||
|
|
||||||
|
/* Stack location is first item in the TCB. */
|
||||||
|
movl pxCurrentTCB, %eax
|
||||||
|
movl (%eax), %esp
|
||||||
|
|
||||||
|
.if configSUPPORT_FPU == 1
|
||||||
|
|
||||||
|
/* Restore address of task's FPU context buffer. */
|
||||||
|
pop pucPortTaskFPUContextBuffer
|
||||||
|
|
||||||
|
/* If the task has a buffer allocated in which its FPU context is saved,
|
||||||
|
then restore it now. */
|
||||||
|
movl pucPortTaskFPUContextBuffer, %eax
|
||||||
|
test %eax, %eax
|
||||||
|
je 1f
|
||||||
|
frstor ( %eax )
|
||||||
|
1:
|
||||||
|
.endif
|
||||||
|
|
||||||
|
popa
|
||||||
|
|
||||||
|
/* EOI. */
|
||||||
|
movl $0x00, (0xFEE000B0)
|
||||||
|
iret
|
||||||
|
|
||||||
|
.endfunc
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
.if configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
.func vPortCentralInterruptWrapper
|
||||||
|
vPortCentralInterruptWrapper:
|
||||||
|
|
||||||
|
portFREERTOS_INTERRUPT_ENTRY
|
||||||
|
|
||||||
|
movl $0xFEE00170, %eax /* Highest In Service Register (ISR) long word. */
|
||||||
|
movl $8, %ecx /* Loop counter. */
|
||||||
|
|
||||||
|
next_isr_long_word:
|
||||||
|
test %ecx, %ecx /* Loop counter reached 0? */
|
||||||
|
je wrapper_epilogue /* Looked at all ISR registers without finding a bit set. */
|
||||||
|
sub $1, %ecx /* Sub 1 from loop counter. */
|
||||||
|
movl (%eax), %ebx /* Load next ISR long word. */
|
||||||
|
sub $0x10, %eax /* Point to next ISR long word in case no bits are set in the current long word. */
|
||||||
|
test %ebx, %ebx /* Are there any bits set? */
|
||||||
|
je next_isr_long_word /* Look at next ISR long word if no bits were set. */
|
||||||
|
sti
|
||||||
|
bsr %ebx, %ebx /* A bit was set, which one? */
|
||||||
|
movl $32, %eax /* Destination operand for following multiplication. */
|
||||||
|
mul %ecx /* Calculate base vector for current register, 32 vectors per register. */
|
||||||
|
add %ebx, %eax /* Add bit offset into register to get final vector number. */
|
||||||
|
push %eax /* Vector number is function parameter. */
|
||||||
|
call vPortCentralInterruptHandler
|
||||||
|
pop %eax /* Remove parameter. */
|
||||||
|
|
||||||
|
wrapper_epilogue:
|
||||||
|
portFREERTOS_INTERRUPT_EXIT
|
||||||
|
|
||||||
|
.endfunc
|
||||||
|
|
||||||
|
.endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
.func vPortAPISpuriousHandler
|
||||||
|
vPortAPICSpuriousHandler:
|
||||||
|
iret
|
||||||
|
|
||||||
|
.endfunc
|
||||||
|
|
||||||
|
.end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,333 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE uint32_t
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
typedef portSTACK_TYPE StackType_t;
|
||||||
|
typedef long BaseType_t;
|
||||||
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
|
typedef uint32_t TickType_t;
|
||||||
|
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffUL )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 32
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task utilities. */
|
||||||
|
|
||||||
|
/* The interrupt priority (for vectors 16 to 255) is determined using vector/16.
|
||||||
|
The quotient is rounded to the nearest integer with 1 being the lowest priority
|
||||||
|
and 15 is the highest. Therefore the following two interrupts are at the lowest
|
||||||
|
priority. *NOTE 1* If the yield vector is changed then it must also be changed
|
||||||
|
in the portYIELD_INTERRUPT definition immediately below. */
|
||||||
|
#define portAPIC_TIMER_INT_VECTOR ( 0x21 )
|
||||||
|
#define portAPIC_YIELD_INT_VECTOR ( 0x20 )
|
||||||
|
|
||||||
|
/* Build yield interrupt instruction. */
|
||||||
|
#define portYIELD_INTERRUPT "int $0x20"
|
||||||
|
|
||||||
|
/* APIC register addresses. */
|
||||||
|
#define portAPIC_EOI ( *( ( volatile uint32_t * ) 0xFEE000B0UL ) )
|
||||||
|
|
||||||
|
/* APIC bit definitions. */
|
||||||
|
#define portAPIC_ENABLE_BIT ( 1UL << 8UL )
|
||||||
|
#define portAPIC_TIMER_PERIODIC ( 1UL << 17UL )
|
||||||
|
#define portAPIC_DISABLE ( 1UL << 16UL )
|
||||||
|
#define portAPIC_NMI ( 4 << 8)
|
||||||
|
#define portAPIC_DIV_16 ( 0x03 )
|
||||||
|
|
||||||
|
/* Define local API register addresses. */
|
||||||
|
#define portAPIC_ID_REGISTER ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x20UL ) ) )
|
||||||
|
#define portAPIC_SPURIOUS_INT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xF0UL ) ) )
|
||||||
|
#define portAPIC_LVT_TIMER ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x320UL ) ) )
|
||||||
|
#define portAPIC_TIMER_INITIAL_COUNT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x380UL ) ) )
|
||||||
|
#define portAPIC_TIMER_CURRENT_COUNT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x390UL ) ) )
|
||||||
|
#define portAPIC_TASK_PRIORITY ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x80UL ) ) )
|
||||||
|
#define portAPIC_LVT_ERROR ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x370UL ) ) )
|
||||||
|
#define portAPIC_ERROR_STATUS ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x280UL ) ) )
|
||||||
|
#define portAPIC_LDR ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xD0UL ) ) )
|
||||||
|
#define portAPIC_TMRDIV ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x3E0UL ) ) )
|
||||||
|
#define portAPIC_LVT_PERF ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x340UL ) ) )
|
||||||
|
#define portAPIC_LVT_LINT0 ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x350UL ) ) )
|
||||||
|
#define portAPIC_LVT_LINT1 ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x360UL ) ) )
|
||||||
|
|
||||||
|
/* Don't yield if inside a critical section - instead hold the yield pending
|
||||||
|
so it is performed when the critical section is exited. */
|
||||||
|
#define portYIELD() \
|
||||||
|
{ \
|
||||||
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
|
extern volatile uint32_t ulPortYieldPending; \
|
||||||
|
if( ulCriticalNesting != 0 ) \
|
||||||
|
{ \
|
||||||
|
ulPortYieldPending = pdTRUE; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
__asm volatile( portYIELD_INTERRUPT ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called at the end of an ISR that can cause a context switch - pend a yield if
|
||||||
|
xSwithcRequired is not false. */
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
|
{ \
|
||||||
|
extern volatile uint32_t ulPortYieldPending; \
|
||||||
|
if( xSwitchRequired != pdFALSE ) \
|
||||||
|
{ \
|
||||||
|
ulPortYieldPending = 1; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Same as portEND_SWITCHING_ISR() - take your pick which name to use. */
|
||||||
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Critical section control
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical sections for use in interrupts. */
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask( x )
|
||||||
|
|
||||||
|
extern void vPortEnterCritical( void );
|
||||||
|
extern void vPortExitCritical( void );
|
||||||
|
extern uint32_t ulPortSetInterruptMask( void );
|
||||||
|
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
||||||
|
|
||||||
|
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||||
|
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
#define portDISABLE_INTERRUPTS() __asm volatile( "cli" )
|
||||||
|
#define portENABLE_INTERRUPTS() __asm volatile( "sti" )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
|
not required for this port but included in case common demo code that uses these
|
||||||
|
macros is used. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
/* Architecture specific optimisations. */
|
||||||
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \
|
||||||
|
__asm volatile( "bsr %1, %0\n\t" \
|
||||||
|
:"=r"(uxTopPriority) : "rm"(uxReadyPriorities) : "cc" )
|
||||||
|
|
||||||
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
#define portNOP() __asm volatile( "NOP" )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Misc
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portNUM_VECTORS 256
|
||||||
|
#define portMAX_PRIORITY 15
|
||||||
|
typedef void ( *ISR_Handler_t ) ( void );
|
||||||
|
|
||||||
|
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
||||||
|
before any floating point instructions are executed. */
|
||||||
|
#ifndef configSUPPORT_FPU
|
||||||
|
#define configSUPPORT_FPU 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if configSUPPORT_FPU == 1
|
||||||
|
void vPortTaskUsesFPU( void );
|
||||||
|
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* See the comments under the configUSE_COMMON_INTERRUPT_ENTRY_POINT definition
|
||||||
|
below. */
|
||||||
|
BaseType_t xPortRegisterCInterruptHandler( ISR_Handler_t pxHandler, uint32_t ulVectorNumber );
|
||||||
|
BaseType_t xPortInstallInterruptHandler( ISR_Handler_t pxHandler, uint32_t ulVectorNumber );
|
||||||
|
|
||||||
|
#ifndef configAPIC_BASE
|
||||||
|
/* configAPIC_BASE_ADDRESS sets the base address of the local APIC. It can
|
||||||
|
be overridden in FreeRTOSConfig.h should it not be constant. */
|
||||||
|
#define configAPIC_BASE 0xFEE00000UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
/* The FreeRTOS scheduling algorithm selects the task that will enter the
|
||||||
|
Running state. configUSE_PORT_OPTIMISED_TASK_SELECTION is used to set how
|
||||||
|
that is done.
|
||||||
|
|
||||||
|
If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 0 then the task to
|
||||||
|
enter the Running state is selected using a portable algorithm written in
|
||||||
|
C. This is the slowest method, but the algorithm does not restrict the
|
||||||
|
maximum number of unique RTOS task priorities that are available.
|
||||||
|
|
||||||
|
If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 1 then the task to
|
||||||
|
enter the Running state is selected using a single assembly instruction.
|
||||||
|
This is the fastest method, but restricts the maximum number of unique RTOS
|
||||||
|
task priorities to 32 (the same task priority can be assigned to any number
|
||||||
|
of RTOS tasks). */
|
||||||
|
#warning configUSE_PORT_OPTIMISED_TASK_SELECTION was not defined in FreeRTOSConfig.h and has been defaulted to 1
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_COMMON_INTERRUPT_ENTRY_POINT
|
||||||
|
/* There are two ways of implementing interrupt handlers:
|
||||||
|
|
||||||
|
1) As standard C functions -
|
||||||
|
|
||||||
|
This method can only be used if configUSE_COMMON_INTERRUPT_ENTRY_POINT
|
||||||
|
is set to 1. The C function is installed using
|
||||||
|
xPortRegisterCInterruptHandler().
|
||||||
|
|
||||||
|
This is the simplest of the two methods but incurs a slightly longer
|
||||||
|
interrupt entry time.
|
||||||
|
|
||||||
|
2) By using an assembly stub that wraps the handler in the FreeRTOS
|
||||||
|
portFREERTOS_INTERRUPT_ENTRY and portFREERTOS_INTERRUPT_EXIT macros.
|
||||||
|
|
||||||
|
This method can always be used. It is slightly more complex than
|
||||||
|
method 1 but benefits from a faster interrupt entry time. */
|
||||||
|
#warning config_USE_COMMON_INTERRUPT_ENTRY_POINT was not defined in FreeRTOSConfig.h and has been defaulted to 1.
|
||||||
|
#define configUSE_COMMON_INTERRUPT_ENTRY_POINT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configISR_STACK_SIZE
|
||||||
|
/* Interrupt entry code will switch the stack in use to a dedicated system
|
||||||
|
stack.
|
||||||
|
|
||||||
|
configISR_STACK_SIZE defines the number of 32-bit values that can be stored
|
||||||
|
on the system stack, and must be large enough to hold a potentially nested
|
||||||
|
interrupt stack frame. */
|
||||||
|
|
||||||
|
#error configISE_STACK_SIZE was not defined in FreeRTOSConfig.h.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
||||||
|
/* Interrupt safe FreeRTOS functions (those that end in "FromISR" must not
|
||||||
|
be called from an interrupt that has a priority above that set by
|
||||||
|
configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||||
|
#warning configMAX_API_CALL_INTERRUPT_PRIORITY was not defined in FreeRTOSConfig.h and has been defaulted to 10
|
||||||
|
#define configMAX_API_CALL_INTERRUPT_PRIORITY 10
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configSUPPORT_FPU
|
||||||
|
#warning configSUPPORT_FPU was not defined in FreeRTOSConfig.h and has been defaulted to 0
|
||||||
|
#define configSUPPORT_FPU 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The value written to the task priority register to raise the interrupt mask
|
||||||
|
to the maximum from which FreeRTOS API calls can be made. */
|
||||||
|
#define portAPIC_PRIORITY_SHIFT ( 4UL )
|
||||||
|
#define portAPIC_MAX_SUB_PRIORITY ( 0x0fUL )
|
||||||
|
#define portMAX_API_CALL_PRIORITY ( ( configMAX_API_CALL_INTERRUPT_PRIORITY << portAPIC_PRIORITY_SHIFT ) | portAPIC_MAX_SUB_PRIORITY )
|
||||||
|
|
||||||
|
/* Asserts if interrupt safe FreeRTOS functions are called from a priority
|
||||||
|
above the max system call interrupt priority. */
|
||||||
|
#define portAPIC_PROCESSOR_PRIORITY ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xA0UL ) ) )
|
||||||
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( portAPIC_PROCESSOR_PRIORITY ) <= ( portMAX_API_CALL_PRIORITY ) )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern C */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
Loading…
Reference in New Issue