Preparing for the next release...

New port and demo project:  Intel Galileo.
This commit is contained in:
Richard Barry 2015-07-30 11:46:30 +00:00
parent 8b5c27b679
commit cff5cfdd4f
36 changed files with 8158 additions and 0 deletions

View File

@ -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="&quot;${workspace_loc:/${ProjName}/Full_Demo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Full_Demo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Support_Files}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/FreeRTOS_Source/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Full_Demo/Standard_Demo_Tasks/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/FreeRTOS_Source/portable/IA32_flat}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
</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="&quot;${workspace_loc:/${ProjName}}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/FreeRTOS_Source/portable/IA32_flat}&quot;"/>
</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>

View File

@ -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>

View File

@ -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 &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>

View File

@ -0,0 +1,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}}

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false

View File

@ -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;
}
}
}
/*-----------------------------------------------------------*/

View File

@ -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 */

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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;
}
}
}
/*-----------------------------------------------------------*/

View File

@ -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=

View File

@ -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);
}
/*-----------------------------------------------------------*/

View File

@ -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__ */

View File

@ -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
}
/*-----------------------------------------------------------*/

View File

@ -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 */

View File

@ -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;
}

View File

@ -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++);
}
}
/*-----------------------------------------------------------*/

View File

@ -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 */

View File

@ -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__ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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) }
}

View File

@ -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;
}

View File

@ -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

View File

@ -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 );
}

View File

@ -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

View File

@ -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 */