diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.cproject b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.cproject new file mode 100644 index 000000000..f2e685fa5 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.cproject @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.project b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.project new file mode 100644 index 000000000..cb166f05f --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.project @@ -0,0 +1,73 @@ + + + RTOSDemo + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + FreeRTOS_Source + 2 + FREERTOS_ROOT/Source + + + Full_Demo/Standard_Demo_Tasks + 2 + FREERTOS_ROOT/Demo/Common + + + + + 1397138529515 + FreeRTOS_Source/portable + 9 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-IA32_flat + + + + 1397138529531 + FreeRTOS_Source/portable + 9 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-MemMang + + + + 1397138545742 + FreeRTOS_Source/portable/MemMang + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-heap_4.c + + + + + + FREERTOS_ROOT + $%7BPARENT-2-PROJECT_LOC%7D + + + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.settings/language.settings.xml b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.settings/language.settings.xml new file mode 100644 index 000000000..07787ce94 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.settings/language.settings.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.settings/org.eclipse.cdt.codan.core.prefs b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.settings/org.eclipse.cdt.codan.core.prefs new file mode 100644 index 000000000..1b270792f --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.settings/org.eclipse.cdt.codan.core.prefs @@ -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}} diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.settings/org.eclipse.cdt.core.prefs b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.settings/org.eclipse.cdt.core.prefs new file mode 100644 index 000000000..4cb254bc3 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.settings/org.eclipse.cdt.core.prefs @@ -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 diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.settings/org.eclipse.cdt.managedbuilder.core.prefs b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.settings/org.eclipse.cdt.managedbuilder.core.prefs new file mode 100644 index 000000000..7530bd4cf --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.settings/org.eclipse.cdt.managedbuilder.core.prefs @@ -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 diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.settings/org.eclipse.ltk.core.refactoring.prefs b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.settings/org.eclipse.ltk.core.refactoring.prefs new file mode 100644 index 000000000..cfcd1d3c2 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/.settings/org.eclipse.ltk.core.refactoring.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Blinky_Demo/main_blinky.c b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Blinky_Demo/main_blinky.c new file mode 100644 index 000000000..61977efc9 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Blinky_Demo/main_blinky.c @@ -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; + } + } +} +/*-----------------------------------------------------------*/ + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/FreeRTOSConfig.h b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/FreeRTOSConfig.h new file mode 100644 index 000000000..adcdf61e8 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/FreeRTOSConfig.h @@ -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 */ + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Full_Demo/IntQueueTimer.c b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Full_Demo/IntQueueTimer.c new file mode 100644 index 000000000..d230aada8 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Full_Demo/IntQueueTimer.c @@ -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; + } +} + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Full_Demo/IntQueueTimer.h b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Full_Demo/IntQueueTimer.h new file mode 100644 index 000000000..77de77259 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Full_Demo/IntQueueTimer.h @@ -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 + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Full_Demo/RegTest.S b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Full_Demo/RegTest.S new file mode 100644 index 000000000..6f09608ea --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Full_Demo/RegTest.S @@ -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 diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Full_Demo/main_full.c b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Full_Demo/main_full.c new file mode 100644 index 000000000..a6cbc8ea0 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Full_Demo/main_full.c @@ -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 +#include +#include +#include + +/* 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; + } + } +} +/*-----------------------------------------------------------*/ + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Instructions_Read_Me.url b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Instructions_Read_Me.url new file mode 100644 index 000000000..05a7f3adb --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Instructions_Read_Me.url @@ -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= diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/GPIO_I2C.c b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/GPIO_I2C.c new file mode 100644 index 000000000..47c20e22d --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/GPIO_I2C.c @@ -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); + } + /*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/GPIO_I2C.h b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/GPIO_I2C.h new file mode 100644 index 000000000..d6ae92743 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/GPIO_I2C.h @@ -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__ */ + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/HPET.c b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/HPET.c new file mode 100644 index 000000000..c97d1f6c6 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/HPET.c @@ -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 +} +/*-----------------------------------------------------------*/ + + + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/HPET.h b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/HPET.h new file mode 100644 index 000000000..57b52dcd2 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/HPET.h @@ -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 */ + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/freestanding_functions.c b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/freestanding_functions.c new file mode 100644 index 000000000..f495e168e --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/freestanding_functions.c @@ -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 + +/*-----------------------------------------------------------*/ + +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; +} + + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/galileo-support.c b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/galileo-support.c new file mode 100644 index 000000000..0cebd3646 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/galileo-support.c @@ -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++); + } + } + /*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/galileo_gen_defs.h b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/galileo_gen_defs.h new file mode 100644 index 000000000..7ebadc877 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/galileo_gen_defs.h @@ -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 +#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 */ + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/galileo_support.h b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/galileo_support.h new file mode 100644 index 000000000..00cd93207 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/galileo_support.h @@ -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__ */ + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/math.h b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/math.h new file mode 100644 index 000000000..bd0f18c15 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/math.h @@ -0,0 +1,75 @@ +/* + FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef MATH_H +#define MATH_H + +double fabs( double x ); + +#endif /* math_h */ diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/multiboot.h b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/multiboot.h new file mode 100644 index 000000000..64dea6ea7 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/multiboot.h @@ -0,0 +1,89 @@ +/* + * Multiboot OS definitions and structures. + */ + +#ifndef _MULTIBOOT_H_ +#define _MULTIBOOT_H_ + +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 +#define MULTIBOOT_HEADER_FLAGS 0x00010003 +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +typedef unsigned long t_32 ; + +typedef struct multiboot_header + { + t_32 Magic; + t_32 flags; + t_32 checksum; + t_32 header_addr; + t_32 load_addr; + t_32 load_end_addr; + t_32 bss_end_addr; + t_32 entry_addr; + t_32 video_mode; + t_32 width; + t_32 height; + t_32 depth; +} multiboot_header_t; + +/* Symbol table for a.out. */ +typedef struct aout_symbol_table +{ + t_32 tabsize; + t_32 strsize; + t_32 addr; + t_32 reserved; +} aout_symbol_table_t; + +/* Section header table for ELF. */ +typedef struct elf_section_header_table +{ + t_32 num; + t_32 size; + t_32 addr; + t_32 shndx; +} elf_section_header_table_t; + +/* Multiboot information. */ +typedef struct multiboot_info +{ + t_32 flags; + t_32 mem_lower; + t_32 mem_upper; + t_32 boot_device; + t_32 cmdline; + t_32 mods_count; + t_32 mods_addr; + union + { + aout_symbol_table_t aout_sym; + elf_section_header_table_t elf_sec; + } u; + t_32 mmap_length; + t_32 mmap_addr; +} multiboot_info_t; + +/* Module structure. */ +typedef struct module +{ + t_32 mod_start; + t_32 mod_end; + t_32 string; + t_32 reserved; +} module_t; + +/* Memory map. Offset 0 is base_addr_low -no size. */ +typedef struct memory_map +{ + t_32 size; + t_32 base_addr_low; + t_32 base_addr_high; + t_32 length_low; + t_32 length_high; + t_32 type; +} memory_map_t; + +#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit))) + +#endif /* _MULTIBOOT_H_ */ diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/printf-stdarg.c b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/printf-stdarg.c new file mode 100644 index 000000000..a0ab358d9 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/printf-stdarg.c @@ -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 +#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; +} + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/startup.S b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/startup.S new file mode 100644 index 000000000..c288bcacc --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/startup.S @@ -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 diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/stdint.h b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/stdint.h new file mode 100644 index 000000000..90875244d --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/stdint.h @@ -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 */ diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/stdio.h b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/stdio.h new file mode 100644 index 000000000..d879a7357 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/stdio.h @@ -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 */ diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/stdlib.h b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/stdlib.h new file mode 100644 index 000000000..1c518b0c0 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/stdlib.h @@ -0,0 +1,20 @@ +/* + * Temporary file for use only during development when there are no library or + * header files. + */ + + +#ifndef STDLIB_H +#define STDLIB_H + + +/* + * Extremely crude standard library implementations in lieu of having a C + * library. + */ +void *memset( void *pvDest, int iValue, unsigned long ulBytes ); +void *memcpy( void *pvDest, const void *pvSource, unsigned long ulBytes ); +int memcmp( const void *pvMem1, const void *pvMem2, unsigned long ulBytes ); + +#endif /* STDLIB_H */ + diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/string.h b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/string.h new file mode 100644 index 000000000..cc5fa8751 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/string.h @@ -0,0 +1,21 @@ + +/* + * Temporary file for use only during development when there are no library or + * header files. + */ + +#ifndef STRING_H +#define STRING_H + +//typedef unsigned long size_t; + +/* + * Extremely crude standard library implementations in lieu of having a C + * library. + */ +unsigned long strlen( const char* pcString ); +int strcmp( const char *pcString1, const char *pcString2 ); +void *memset( void *pvDest, int iValue, unsigned long ulBytes ); +void *memcpy( void *pvDest, const void *pvSource, unsigned long ulBytes ); +int memcmp( const void *pvMem1, const void *pvMem2, unsigned long ulBytes ); +#endif /* string_h */ diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/elf_ia32_efi.lds b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/elf_ia32_efi.lds new file mode 100644 index 000000000..44aa24781 --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/elf_ia32_efi.lds @@ -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) } + +} \ No newline at end of file diff --git a/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/main.c b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/main.c new file mode 100644 index 000000000..ff2401b6a --- /dev/null +++ b/FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/main.c @@ -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 + +/* 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; +} diff --git a/FreeRTOS/Source/portable/GCC/IA32_flat/ISR_Support.h b/FreeRTOS/Source/portable/GCC/IA32_flat/ISR_Support.h new file mode 100644 index 000000000..10a433564 --- /dev/null +++ b/FreeRTOS/Source/portable/GCC/IA32_flat/ISR_Support.h @@ -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 diff --git a/FreeRTOS/Source/portable/GCC/IA32_flat/port.c b/FreeRTOS/Source/portable/GCC/IA32_flat/port.c new file mode 100644 index 000000000..e27719517 --- /dev/null +++ b/FreeRTOS/Source/portable/GCC/IA32_flat/port.c @@ -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 + +/* 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 ); +} + + + + + + + + + + + + + + diff --git a/FreeRTOS/Source/portable/GCC/IA32_flat/portASM.S b/FreeRTOS/Source/portable/GCC/IA32_flat/portASM.S new file mode 100644 index 000000000..a8029ae49 --- /dev/null +++ b/FreeRTOS/Source/portable/GCC/IA32_flat/portASM.S @@ -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 + + + + + + + diff --git a/FreeRTOS/Source/portable/GCC/IA32_flat/portmacro.h b/FreeRTOS/Source/portable/GCC/IA32_flat/portmacro.h new file mode 100644 index 000000000..4cf7dc8dd --- /dev/null +++ b/FreeRTOS/Source/portable/GCC/IA32_flat/portmacro.h @@ -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 */ +