Add Xtensa port

The project file is for Xtensa Xplorer simulator.
Also add tests for one size stream buffer.
pull/4/head
Gaurav Aggarwal 7 years ago
parent 7d92e4dd8f
commit c4b1afc4ef

@ -783,9 +783,9 @@ const TickType_t xTicksToBlock = pdMS_TO_TICKS( 250UL );
memset( pcReceivedString, 0x00, mbMESSAGE_BUFFER_LENGTH_BYTES );
/* Has any data been sent by the client? */
xReceivedLength = xMessageBufferReceive( xMessageBuffers.xEchoClientBuffer, ( void * ) pcReceivedString, mbMESSAGE_BUFFER_LENGTH_BYTES, xTicksToBlock );
xReceivedLength = xMessageBufferReceive( xMessageBuffers.xEchoClientBuffer, ( void * ) pcReceivedString, mbMESSAGE_BUFFER_LENGTH_BYTES, portMAX_DELAY );
/* Should always receive data as a delay was used. */
/* Should always receive data as max delay was used. */
configASSERT( xReceivedLength > 0 );
/* Echo the received data back to the client. */

@ -40,6 +40,9 @@
/* The number of bytes of storage in the stream buffers used in this test. */
#define sbSTREAM_BUFFER_LENGTH_BYTES ( ( size_t ) 30 )
/* Stream buffer length one. */
#define sbSTREAM_BUFFER_LENGTH_ONE ( ( size_t ) 1 )
/* Start and end ASCII characters used in data sent to the buffers. */
#define sbASCII_SPACE 32
#define sbASCII_TILDA 126
@ -768,6 +771,51 @@ EchoStreamBuffers_t *pxStreamBuffers = ( EchoStreamBuffers_t * ) pvParameters;
xTempStreamBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_BYTES, sbTRIGGER_LEVEL_1 );
prvSingleTaskTests( xTempStreamBuffer );
vStreamBufferDelete( xTempStreamBuffer );
/* The following are tests for a stream buffer of size one. */
/* Create a buffer of size one. */
xTempStreamBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_ONE, sbTRIGGER_LEVEL_1 );
/* Ensure that the buffer was created successfully. */
configASSERT( xTempStreamBuffer );
/* Send one byte to the buffer. */
ux = xStreamBufferSend( xTempStreamBuffer, ( void * ) pcStringToSend, ( size_t ) 1, sbDONT_BLOCK );
/* Ensure that the byte was sent successfully. */
configASSERT( ux == 1 );
/* Try sending another byte to the buffer. */
ux = xStreamBufferSend( xTempStreamBuffer, ( void * ) pcStringToSend, ( size_t ) 1, sbDONT_BLOCK );
/* Make sure that send failed as the buffer is full. */
configASSERT( ux == 0 );
/* Receive one byte from the buffer. */
memset( pcStringReceived, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES );
ux = xStreamBufferReceive( xTempStreamBuffer, ( void * ) pcStringReceived, ( size_t ) 1, sbDONT_BLOCK );
/* Ensure that the receive was successful. */
configASSERT( ux == 1 );
/* Ensure that the correct data was received. */
configASSERT( pcStringToSend[ 0 ] == pcStringReceived[ 0 ] );
/* Try receiving another byte from the buffer. */
ux = xStreamBufferReceive( xTempStreamBuffer, ( void * ) pcStringReceived, ( size_t ) 1, sbDONT_BLOCK );
/* Ensure that the receive failed as the buffer is empty. */
configASSERT( ux == 0 );
/* Try sending two bytes to the buffer. Since the size of the
* buffer is one, we must not be able to send more than one. */
ux = xStreamBufferSend( xTempStreamBuffer, ( void * ) pcStringToSend, ( size_t ) 2, sbDONT_BLOCK );
/* Ensure that only one byte was sent. */
configASSERT( ux == 1 );
/* Try receiving two bytes from the buffer. Since the size of the
* buffer is one, we must not be able to get more than one. */
memset( pcStringReceived, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES );
ux = xStreamBufferReceive( xTempStreamBuffer, ( void * ) pcStringReceived, ( size_t ) 2, sbDONT_BLOCK );
/* Ensure that only one byte was received. */
configASSERT( ux == 1 );
/* Ensure that the correct data was received. */
configASSERT( pcStringToSend[ 0 ] == pcStringReceived[ 0 ] );
/* Delete the buffer. */
vStreamBufferDelete( xTempStreamBuffer );
}
}
/*-----------------------------------------------------------*/
@ -822,9 +870,9 @@ const TickType_t xTicksToBlock = pdMS_TO_TICKS( 350UL );
memset( pcReceivedString, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES );
/* Has any data been sent by the client? */
xReceivedLength = xStreamBufferReceive( xStreamBuffers.xEchoClientBuffer, ( void * ) pcReceivedString, sbSTREAM_BUFFER_LENGTH_BYTES, xTicksToBlock );
xReceivedLength = xStreamBufferReceive( xStreamBuffers.xEchoClientBuffer, ( void * ) pcReceivedString, sbSTREAM_BUFFER_LENGTH_BYTES, portMAX_DELAY );
/* Should always receive data as a delay was used. */
/* Should always receive data as max delay was used. */
prvCheckExpectedState( xReceivedLength > 0 );
/* Echo the received data back to the client. */

@ -0,0 +1,214 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<buildSystem id="Xtensa.600602548">
<storageModule id="Xtensa.600602548" moduleId="org.eclipse.cdt.core.settings"/>
</buildSystem>
<cconfiguration id="Xtensa.600602548">
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration buildProperties="" description="" errorParsers="org.eclipse.cdt.core.VCErrorParser;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.CWDLocator;com.tensilica.xide.cdt.XCCErrorParser;org.eclipse.cdt.core.GASErrorParser;com.tensilica.xide.cdt.XtLDErrorParser;com.tensilica.xide.cdt.TCErrorParser;com.tensilica.xide.cdt.FlexLmErrorParser" id="Xtensa.600602548" name="Xtensa" parent="org.eclipse.cdt.build.core.prefbase.cfg">
<folderInfo id="Xtensa.600602548." name="/" resourcePath="">
<toolChain errorParsers="" id="org.eclipse.cdt.build.core.prefbase.toolchain.1124911838" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
<targetPlatform binaryParser="com.tensilica.xide.cdt.XtensaELF" id="org.eclipse.cdt.build.core.prefbase.toolchain.1124911838.1653706502" name=""/>
<builder command="${default_xttools_make_path}" enableAutoBuild="false" errorParsers="org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.CWDLocator" id="org.eclipse.cdt.build.core.settings.default.builder.1420142413" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder">
<outputEntries>
<entry excluding="**/.genned|**/*.pstamp|**/*.props|**/*.d|**/objFiles.list|**/*.interlock|**/*.icmiss|**/*.dcmiss|**/*.icmiss_cyc|**/*.dcmiss_cyc|**/*.cc_miss|**/*.cc_miss_cyc|**/*.cyc|**/*.insn|**/*.bdelay" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name="bin"/>
</outputEntries>
</builder>
<tool errorParsers="org.eclipse.cdt.core.VCErrorParser;org.eclipse.cdt.core.GASErrorParser" id="org.eclipse.cdt.build.core.settings.holder.libs.283188354" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
<tool errorParsers="org.eclipse.cdt.core.VCErrorParser;org.eclipse.cdt.core.GASErrorParser" id="org.eclipse.cdt.build.core.settings.holder.1363672131" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
<option id="org.eclipse.cdt.build.core.settings.holder.incpaths.818579882" name="Include Paths" superClass="org.eclipse.cdt.build.core.settings.holder.incpaths" valueType="includePath">
<listOptionValue builtIn="false" value="C:/workplace/FreeRTOSSVN/FreeRTOS/Demo/Tensilica_Simulator_Xplorer_XCC"/>
<listOptionValue builtIn="false" value="C:/workplace/FreeRTOSSVN/FreeRTOS/Demo/Common/include"/>
<listOptionValue builtIn="false" value="C:/workplace/FreeRTOSSVN/FreeRTOS/Source/include"/>
<listOptionValue builtIn="false" value="C:/workplace/FreeRTOSSVN/FreeRTOS/Source/portable/ThirdParty/XCC/Xtensa"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/builds/RG-2017.8-win32/sample_controller/xtensa-elf/arch/include"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/builds/RG-2017.8-win32/sample_controller/xtensa-elf/include"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/tools/RG-2017.8-win32/XtensaTools/lib/xcc/include"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/tools/RG-2017.8-win32/XtensaTools/xtensa-elf/include"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/builds/RG-2017.8-win32/sample_controller/xtensa-elf/include/xcc/c++"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/builds/RG-2017.8-win32/sample_controller/xtensa-elf/include/xcc/c++/xtensa-elf"/>
</option>
<option id="org.eclipse.cdt.build.core.settings.holder.symbols.1072492848" name="Symbols" superClass="org.eclipse.cdt.build.core.settings.holder.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__CHAR_BIT__=8"/>
<listOptionValue builtIn="false" value="__WCHAR_MAX__=65535U"/>
<listOptionValue builtIn="false" value="__FLT_EVAL_METHOD__=0"/>
<listOptionValue builtIn="false" value="__FINITE_MATH_ONLY__=0"/>
<listOptionValue builtIn="false" value="__GNUC_PATCHLEVEL__=0"/>
<listOptionValue builtIn="false" value="__SHRT_MAX__=32767"/>
<listOptionValue builtIn="false" value="__UINTMAX_TYPE__=long"/>
<listOptionValue builtIn="false" value="__CHAR_UNSIGNED__=1"/>
<listOptionValue builtIn="false" value="__XCC__=12000"/>
<listOptionValue builtIn="false" value="__SCHAR_MAX__=127"/>
<listOptionValue builtIn="false" value="__USER_LABEL_PREFIX__"/>
<listOptionValue builtIn="false" value="__STDC_HOSTED__=1"/>
<listOptionValue builtIn="false" value="__XTENSA_EL__=1"/>
<listOptionValue builtIn="false" value="__XCC_MINOR__=8"/>
<listOptionValue builtIn="false" value="__GNUC__=4"/>
<listOptionValue builtIn="false" value="__LONG_LONG_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__GXX_ABI_VERSION=1002"/>
<listOptionValue builtIn="false" value="__REGISTER_PREFIX__"/>
<listOptionValue builtIn="false" value="__NO_INLINE__=1"/>
<listOptionValue builtIn="false" value="__VERSION__=&quot;4.2.0"/>
<listOptionValue builtIn="false" value="__XTENSA_SOFT_FLOAT__=1"/>
<listOptionValue builtIn="false" value="__SIZE_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__ELF__=1"/>
<listOptionValue builtIn="false" value="__xtensa__=1"/>
<listOptionValue builtIn="false" value="__LONG_MAX__=2147483647L"/>
<listOptionValue builtIn="false" value="__WCHAR_TYPE__=short"/>
<listOptionValue builtIn="false" value="__INT_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__WINT_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__XTENSA_WINDOWED_ABI__=1"/>
<listOptionValue builtIn="false" value="__XTENSA__=1"/>
<listOptionValue builtIn="false" value="__INTMAX_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__INTMAX_TYPE__=long"/>
<listOptionValue builtIn="false" value="__XTENSA_SOFT_DOUBLE__=1"/>
<listOptionValue builtIn="false" value="__GNUC_MINOR__=2"/>
<listOptionValue builtIn="false" value="__STDC__=1"/>
<listOptionValue builtIn="false" value="__PTRDIFF_TYPE__=int"/>
<listOptionValue builtIn="false" value="__GNUC_GNU_INLINE__=1"/>
</option>
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1208833786" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool errorParsers="org.eclipse.cdt.core.VCErrorParser;org.eclipse.cdt.core.GASErrorParser" id="org.eclipse.cdt.build.core.settings.holder.29534978" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
<option id="org.eclipse.cdt.build.core.settings.holder.incpaths.1529034681" name="Include Paths" superClass="org.eclipse.cdt.build.core.settings.holder.incpaths" valueType="includePath">
<listOptionValue builtIn="false" value="C:/workplace/FreeRTOSSVN/FreeRTOS/Demo/Tensilica_Simulator_Xplorer_XCC"/>
<listOptionValue builtIn="false" value="C:/workplace/FreeRTOSSVN/FreeRTOS/Demo/Common/include"/>
<listOptionValue builtIn="false" value="C:/workplace/FreeRTOSSVN/FreeRTOS/Source/include"/>
<listOptionValue builtIn="false" value="C:/workplace/FreeRTOSSVN/FreeRTOS/Source/portable/ThirdParty/XCC/Xtensa"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/builds/RG-2017.8-win32/sample_controller/xtensa-elf/arch/include"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/builds/RG-2017.8-win32/sample_controller/xtensa-elf/include"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/tools/RG-2017.8-win32/XtensaTools/lib/xcc/include"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/tools/RG-2017.8-win32/XtensaTools/xtensa-elf/include"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/builds/RG-2017.8-win32/sample_controller/xtensa-elf/include/xcc/c++"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/builds/RG-2017.8-win32/sample_controller/xtensa-elf/include/xcc/c++/xtensa-elf"/>
</option>
<option id="org.eclipse.cdt.build.core.settings.holder.symbols.459736431" name="Symbols" superClass="org.eclipse.cdt.build.core.settings.holder.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__CHAR_BIT__=8"/>
<listOptionValue builtIn="false" value="__WCHAR_MAX__=65535U"/>
<listOptionValue builtIn="false" value="__FLT_EVAL_METHOD__=0"/>
<listOptionValue builtIn="false" value="__FINITE_MATH_ONLY__=0"/>
<listOptionValue builtIn="false" value="__GNUC_PATCHLEVEL__=0"/>
<listOptionValue builtIn="false" value="__SHRT_MAX__=32767"/>
<listOptionValue builtIn="false" value="__UINTMAX_TYPE__=long"/>
<listOptionValue builtIn="false" value="__CHAR_UNSIGNED__=1"/>
<listOptionValue builtIn="false" value="__XCC__=12000"/>
<listOptionValue builtIn="false" value="__SCHAR_MAX__=127"/>
<listOptionValue builtIn="false" value="__USER_LABEL_PREFIX__"/>
<listOptionValue builtIn="false" value="__STDC_HOSTED__=1"/>
<listOptionValue builtIn="false" value="__XTENSA_EL__=1"/>
<listOptionValue builtIn="false" value="__XCC_MINOR__=8"/>
<listOptionValue builtIn="false" value="__GNUC__=4"/>
<listOptionValue builtIn="false" value="__LONG_LONG_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__GXX_ABI_VERSION=1002"/>
<listOptionValue builtIn="false" value="__REGISTER_PREFIX__"/>
<listOptionValue builtIn="false" value="__NO_INLINE__=1"/>
<listOptionValue builtIn="false" value="__VERSION__=&quot;4.2.0"/>
<listOptionValue builtIn="false" value="__XTENSA_SOFT_FLOAT__=1"/>
<listOptionValue builtIn="false" value="__SIZE_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__ELF__=1"/>
<listOptionValue builtIn="false" value="__xtensa__=1"/>
<listOptionValue builtIn="false" value="__LONG_MAX__=2147483647L"/>
<listOptionValue builtIn="false" value="__WCHAR_TYPE__=short"/>
<listOptionValue builtIn="false" value="__INT_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__WINT_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__XTENSA_WINDOWED_ABI__=1"/>
<listOptionValue builtIn="false" value="__XTENSA__=1"/>
<listOptionValue builtIn="false" value="__INTMAX_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__INTMAX_TYPE__=long"/>
<listOptionValue builtIn="false" value="__XTENSA_SOFT_DOUBLE__=1"/>
<listOptionValue builtIn="false" value="__GNUC_MINOR__=2"/>
<listOptionValue builtIn="false" value="__STDC__=1"/>
<listOptionValue builtIn="false" value="__PTRDIFF_TYPE__=int"/>
<listOptionValue builtIn="false" value="__GNUC_GNU_INLINE__=1"/>
</option>
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1865337768" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool errorParsers="org.eclipse.cdt.core.VCErrorParser;org.eclipse.cdt.core.GASErrorParser" id="org.eclipse.cdt.build.core.settings.holder.541186543" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
<option id="org.eclipse.cdt.build.core.settings.holder.incpaths.2101310742" name="Include Paths" superClass="org.eclipse.cdt.build.core.settings.holder.incpaths" valueType="includePath">
<listOptionValue builtIn="false" value="C:/workplace/FreeRTOSSVN/FreeRTOS/Demo/Tensilica_Simulator_Xplorer_XCC"/>
<listOptionValue builtIn="false" value="C:/workplace/FreeRTOSSVN/FreeRTOS/Demo/Common/include"/>
<listOptionValue builtIn="false" value="C:/workplace/FreeRTOSSVN/FreeRTOS/Source/include"/>
<listOptionValue builtIn="false" value="C:/workplace/FreeRTOSSVN/FreeRTOS/Source/portable/ThirdParty/XCC/Xtensa"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/builds/RG-2017.8-win32/sample_controller/xtensa-elf/arch/include"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/builds/RG-2017.8-win32/sample_controller/xtensa-elf/include"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/tools/RG-2017.8-win32/XtensaTools/lib/xcc/include"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/tools/RG-2017.8-win32/XtensaTools/xtensa-elf/include"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/builds/RG-2017.8-win32/sample_controller/xtensa-elf/include/xcc/c++"/>
<listOptionValue builtIn="false" value="C:/usr/xtensa/XtDevTools/install/builds/RG-2017.8-win32/sample_controller/xtensa-elf/include/xcc/c++/xtensa-elf"/>
</option>
<option id="org.eclipse.cdt.build.core.settings.holder.symbols.740810983" name="Symbols" superClass="org.eclipse.cdt.build.core.settings.holder.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__CHAR_BIT__=8"/>
<listOptionValue builtIn="false" value="__WCHAR_MAX__=65535U"/>
<listOptionValue builtIn="false" value="__FLT_EVAL_METHOD__=0"/>
<listOptionValue builtIn="false" value="__FINITE_MATH_ONLY__=0"/>
<listOptionValue builtIn="false" value="__GNUC_PATCHLEVEL__=0"/>
<listOptionValue builtIn="false" value="__SHRT_MAX__=32767"/>
<listOptionValue builtIn="false" value="__UINTMAX_TYPE__=long"/>
<listOptionValue builtIn="false" value="__CHAR_UNSIGNED__=1"/>
<listOptionValue builtIn="false" value="__XCC__=12000"/>
<listOptionValue builtIn="false" value="__SCHAR_MAX__=127"/>
<listOptionValue builtIn="false" value="__USER_LABEL_PREFIX__"/>
<listOptionValue builtIn="false" value="__STDC_HOSTED__=1"/>
<listOptionValue builtIn="false" value="__XTENSA_EL__=1"/>
<listOptionValue builtIn="false" value="__XCC_MINOR__=8"/>
<listOptionValue builtIn="false" value="__GNUC__=4"/>
<listOptionValue builtIn="false" value="__LONG_LONG_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__GXX_ABI_VERSION=1002"/>
<listOptionValue builtIn="false" value="__REGISTER_PREFIX__"/>
<listOptionValue builtIn="false" value="__NO_INLINE__=1"/>
<listOptionValue builtIn="false" value="__VERSION__=&quot;4.2.0"/>
<listOptionValue builtIn="false" value="__XTENSA_SOFT_FLOAT__=1"/>
<listOptionValue builtIn="false" value="__SIZE_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__ELF__=1"/>
<listOptionValue builtIn="false" value="__xtensa__=1"/>
<listOptionValue builtIn="false" value="__LONG_MAX__=2147483647L"/>
<listOptionValue builtIn="false" value="__WCHAR_TYPE__=short"/>
<listOptionValue builtIn="false" value="__INT_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__WINT_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__XTENSA_WINDOWED_ABI__=1"/>
<listOptionValue builtIn="false" value="__XTENSA__=1"/>
<listOptionValue builtIn="false" value="__INTMAX_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__INTMAX_TYPE__=long"/>
<listOptionValue builtIn="false" value="__XTENSA_SOFT_DOUBLE__=1"/>
<listOptionValue builtIn="false" value="__GNUC_MINOR__=2"/>
<listOptionValue builtIn="false" value="__STDC__=1"/>
<listOptionValue builtIn="false" value="__PTRDIFF_TYPE__=int"/>
<listOptionValue builtIn="false" value="__GNUC_GNU_INLINE__=1"/>
</option>
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1982908514" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="Xtensa.600602548" moduleId="org.eclipse.cdt.core.settings" name="Xtensa">
<externalSettings/>
<extensions>
<extension id="com.tensilica.xide.cdt.XtensaELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.tensilica.xide.cdt.FlexLmErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.tensilica.xide.cdt.TCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.tensilica.xide.cdt.XtLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.tensilica.xide.cdt.XCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="RTOSDemo.null.2024905137" name="RTOSDemo"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="Xtensa.600602548">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="refreshScope" versionNumber="1">
<resource resourceType="PROJECT" workspacePath="/RTOSDemo"/>
</storageModule>
</cproject>

@ -0,0 +1,382 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>RTOSDemo</name>
<comment></comment>
<projects>
<project>XtensaInfo</project>
</projects>
<buildSpec>
<buildCommand>
<name>com.tensilica.xide.cdt.xtensamanagedbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
<nature>com.tensilica.xide.cdt.XtensaCProjectNature</nature>
<nature>com.tensilica.xide.cdt.XtensaCProjectExeNature</nature>
<nature>com.tensilica.xide.cdt.XideManagedProjectNature</nature>
</natures>
<linkedResources>
<link>
<name>CommonDemoTasks</name>
<type>2</type>
<locationURI>virtual:/virtual</locationURI>
</link>
<link>
<name>FreeRTOS_Source</name>
<type>2</type>
<locationURI>virtual:/virtual</locationURI>
</link>
<link>
<name>CommonDemoTasks/AbortDelay.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/AbortDelay.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/BlockQ.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/BlockQ.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/EventGroupsDemo.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/EventGroupsDemo.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/GenQTest.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/GenQTest.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/IntQueue.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/IntQueue.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/IntSemTest.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/IntSemTest.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/MessageBufferDemo.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/MessageBufferDemo.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/PollQ.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/PollQ.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/QPeek.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/QPeek.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/QueueOverwrite.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/QueueOverwrite.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/QueueSet.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/QueueSet.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/QueueSetPolling.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/QueueSetPolling.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/StaticAllocation.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/StaticAllocation.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/StreamBufferDemo.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/StreamBufferDemo.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/StreamBufferInterrupt.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/StreamBufferInterrupt.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/TaskNotify.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/TaskNotify.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/TimerDemo.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/TimerDemo.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/blocktim.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/blocktim.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/countsem.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/countsem.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/death.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/death.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/flop.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/flop.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/include</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/include</locationURI>
</link>
<link>
<name>CommonDemoTasks/integer.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/integer.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/recmutex.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/recmutex.c</locationURI>
</link>
<link>
<name>CommonDemoTasks/semtest.c</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/Common/Minimal/semtest.c</locationURI>
</link>
<link>
<name>FreeRTOS_Source/event_groups.c</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/event_groups.c</locationURI>
</link>
<link>
<name>FreeRTOS_Source/include</name>
<type>2</type>
<locationURI>virtual:/virtual</locationURI>
</link>
<link>
<name>FreeRTOS_Source/list.c</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/list.c</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable</name>
<type>2</type>
<locationURI>virtual:/virtual</locationURI>
</link>
<link>
<name>FreeRTOS_Source/queue.c</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/queue.c</locationURI>
</link>
<link>
<name>FreeRTOS_Source/readme.txt</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/readme.txt</locationURI>
</link>
<link>
<name>FreeRTOS_Source/stream_buffer.c</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/stream_buffer.c</locationURI>
</link>
<link>
<name>FreeRTOS_Source/tasks.c</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/tasks.c</locationURI>
</link>
<link>
<name>FreeRTOS_Source/timers.c</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/timers.c</locationURI>
</link>
<link>
<name>FreeRTOS_Source/include/FreeRTOS.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/include/FreeRTOS.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/include/event_groups.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/include/event_groups.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/include/list.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/include/list.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/include/message_buffer.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/include/message_buffer.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/include/mpu_prototypes.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/include/mpu_prototypes.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/include/mpu_wrappers.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/include/mpu_wrappers.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/include/portable.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/include/portable.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/include/projdefs.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/include/projdefs.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/include/queue.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/include/queue.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/include/semphr.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/include/semphr.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/include/stream_buffer.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/include/stream_buffer.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/include/task.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/include/task.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/include/timers.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/include/timers.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/MemMang</name>
<type>2</type>
<locationURI>virtual:/virtual</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC</name>
<type>2</type>
<locationURI>virtual:/virtual</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/MemMang/heap_4.c</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/MemMang/heap_4.c</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/port.c</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/port.c</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/portasm.S</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/portasm.S</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/portbenchmark.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/portbenchmark.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/portclib.c</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/portclib.c</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/portmacro.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/portmacro.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/porttrace.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/porttrace.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/readme_xtensa.txt</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/readme_xtensa.txt</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/xtensa_api.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/xtensa_api.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/xtensa_config.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/xtensa_config.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/xtensa_context.S</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/xtensa_context.S</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/xtensa_context.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/xtensa_context.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/xtensa_init.c</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/xtensa_init.c</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/xtensa_intr.c</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/xtensa_intr.c</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/xtensa_intr_asm.S</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/xtensa_intr_asm.S</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/xtensa_overlay_os_hook.c</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/xtensa_overlay_os_hook.c</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/xtensa_rtos.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/xtensa_rtos.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/xtensa_timer.h</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/xtensa_timer.h</locationURI>
</link>
<link>
<name>FreeRTOS_Source/portable/XCC/xtensa_vectors.S</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/Source/portable/ThirdParty/XCC/Xtensa/xtensa_vectors.S</locationURI>
</link>
</linkedResources>
</projectDescription>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<BuildTarget version="1.0" tool="xtensa">
<BuildSettings>
<BaseSettings path="project">
<LinkerOptions>
<LinkerSupport value="sim" key="-mlsp=" custom="false"/>
</LinkerOptions>
</BaseSettings>
</BuildSettings>
</BuildTarget>

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<BuildTarget tool="xtensa" version="1.0">
<BuildSettings>
<BaseSettings path="project">
<CompilerOptions>
<FlagValueMapOptions>
<FlagValueMapEntry>
<key>Optimization</key>
<value level="0" flag="-O" use="true"/>
</FlagValueMapEntry>
<FlagValueMapEntry>
<key>Debug</key>
<value level="-3" flag="-g" use="true"/>
</FlagValueMapEntry>
</FlagValueMapOptions>
</CompilerOptions>
<AssemblerOptions>
<SingleFlagMapOptions>
<SingleFlagMapEntry>
<key>AssemblerIncludeDebug</key>
<value flag="--gdwarf-2" use="true"/>
</SingleFlagMapEntry>
<SingleFlagMapEntry>
<key>AssemblerLongCall</key>
<value flag="--longcalls" use="true"/>
</SingleFlagMapEntry>
</SingleFlagMapOptions>
</AssemblerOptions>
<LinkerOptions>
<BooleanMapOptions>
<BooleanMapEntry>
<key>CreateMinsize</key>
<value selected="true"/>
</BooleanMapEntry>
</BooleanMapOptions>
<LinkerSupport custom="false" key="-mlsp=" value="sim"/>
</LinkerOptions>
</BaseSettings>
</BuildSettings>
</BuildTarget>

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xxProperties>
<propertyGroup name="project.information">
<version value="3.0"/>
</propertyGroup>
<propertyGroup name="build.property">
<buildTarget defaultTarget="Debug"/>
</propertyGroup>
<propertyGroup name="build.exclusion.data">
<buildExclusionDatas>
<exclusionSet name="Default" selected="1">
<excludedEntry data="/.*/bin/.*"/>
</exclusionSet>
</buildExclusionDatas>
</propertyGroup>
<propertyGroup name="build.auto.includes">
<exportDirs autoConsumeDirs="true" includeDepDirs="true" mode="auto"/>
</propertyGroup>
<propertyGroup name="library.dependencies"/>
<propertyGroup name="build.custom.steps"/>
</xxProperties>

@ -0,0 +1,250 @@
/*
FreeRTOS V9.0.0 - Copyright (C) 2016 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
/* Required for configuration-dependent settings */
#include "xtensa_config.h"
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* Note that the default heap size is deliberately kept small so that
* the build is more likely to succeed for configurations with limited
* memory.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*----------------------------------------------------------*/
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0
#ifdef SMALL_TEST
#define configUSE_TICK_HOOK 0
#else
#define configUSE_TICK_HOOK 1
#endif
#define configTICK_RATE_HZ ( 1000 )
/* Default clock rate for simulator */
#define configCPU_CLOCK_HZ 10000000 //_RB_ was 2MHz
/* This has impact on speed of search for highest priority */
#ifdef SMALL_TEST
#define configMAX_PRIORITIES ( 7 )
#else
#define configMAX_PRIORITIES ( 7 ) //_RB_
#endif
/* Minimal stack size. This may need to be increased for your application */
/* NOTE: The FreeRTOS demos may not work reliably with stack size < 4KB. */
/* The Xtensa-specific examples should be fine with XT_STACK_MIN_SIZE. */
#if !(defined XT_STACK_MIN_SIZE)
#error XT_STACK_MIN_SIZE not defined, did you include xtensa_config.h ?
#endif
#ifdef SMALL_TEST
#define configMINIMAL_STACK_SIZE (XT_STACK_MIN_SIZE)
#else
#define configMINIMAL_STACK_SIZE (XT_STACK_MIN_SIZE > 4096 ? XT_STACK_MIN_SIZE : 4096)
#endif
/* The Xtensa port uses a separate interrupt stack. Adjust the stack size */
/* to suit the needs of your specific application. */
#ifndef configISR_STACK_SIZE
#define configISR_STACK_SIZE 2048
#endif
/* Minimal heap size to make sure examples can run on memory limited
configs. Adjust this to suit your system. */
#ifdef SMALL_TEST
#define configTOTAL_HEAP_SIZE ( ( size_t ) (16 * 1024) )
#else
#define configTOTAL_HEAP_SIZE ( ( size_t ) (512 * 1024) )
#endif
#define configMAX_TASK_NAME_LEN ( 8 )
#define configUSE_TRACE_FACILITY 1 /* Used by vTaskList in main.c */
#define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Used by vTaskList in main.c */
#define configUSE_TRACE_FACILITY_2 0 /* Provided by Xtensa port patch */
#define configBENCHMARK 0 /* Provided by Xtensa port patch */
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 0
#define configQUEUE_REGISTRY_SIZE 0
#ifdef SMALL_TEST
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configCHECK_FOR_STACK_OVERFLOW 0
#else
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configCHECK_FOR_STACK_OVERFLOW 2
#endif
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 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 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
/* The priority at which the tick interrupt runs. This should probably be
kept at 1. */
#define configKERNEL_INTERRUPT_PRIORITY 1
/* The maximum interrupt priority from which FreeRTOS.org API functions can
be called. Only API functions that end in ...FromISR() can be used within
interrupts. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY XCHAL_EXCM_LEVEL
/* XT_USE_THREAD_SAFE_CLIB is defined in xtensa_config.h and can be
overridden from the compiler/make command line. The small test
however always disables C lib thread safety to minimize size. */
#ifdef SMALL_TEST
#define configUSE_NEWLIB_REENTRANT 0
#else
#if (XT_USE_THREAD_SAFE_CLIB > 0u)
#if XT_HAVE_THREAD_SAFE_CLIB
#define configUSE_NEWLIB_REENTRANT 0 //_RB_ 1
#else
#error "Error: thread-safe C library support not available for this C library."
#endif
#else
#define configUSE_NEWLIB_REENTRANT 0
#endif
#endif
/* Test FreeRTOS timers (with timer task) and more. */
/* Some files don't compile if this flag is disabled */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
#ifdef SMALL_TEST
#define INCLUDE_xTimerPendFunctionCall 0
#define INCLUDE_eTaskGetState 0
#define configUSE_QUEUE_SETS 0
#else
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_eTaskGetState 1
#define configUSE_QUEUE_SETS 1
#endif
/* Specific config for XTENSA (these can be deleted and they will take default values) */
#if (!defined XT_SIMULATOR) && (!defined XT_BOARD)
#define configXT_SIMULATOR 1 /* Simulator mode */
#define configXT_BOARD 0 /* Board mode */
#endif
#ifndef SMALL_TEST
#if (!defined XT_INTEXC_HOOKS)
#define configXT_INTEXC_HOOKS 1 /* Exception hooks used by certain tests */
#endif
#if configUSE_TRACE_FACILITY_2
#define configASSERT_2 1 /* Specific to Xtensa port */
#endif
#endif
/* It is a good idea to define configASSERT() while developing. configASSERT()
uses the same semantics as the standard C assert() macro. */
#if !defined __ASSEMBLER__
extern void vAssertCalled( unsigned long ulLine, const char * const pcFileName );
#endif
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __LINE__, __FILE__ )
#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN ( 2 )
#define configCHECK_FOR_STACK_OVERFLOW 2
#endif /* FREERTOS_CONFIG_H */

@ -0,0 +1,156 @@
/*
* FreeRTOS Kernel V10.0.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. If you wish to use our Amazon
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Demo includes. */
#include "IntQueueTimer.h"
#include "IntQueue.h"
/* Xtensa includes. */
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
#include <xtensa_api.h>
#include <xtensa/hal.h>
/*-----------------------------------------------------------*/
/* Check if Timer1 is available. */
#if XCHAL_TIMER1_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
#if XCHAL_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL
#define SECOND_TIMER_AVAILABLE 1
#endif
#endif
#ifndef SECOND_TIMER_AVAILABLE
#define SECOND_TIMER_AVAILABLE 0
#endif
/* Timer0 is used to drive systick and therefore we use Timer1
* as second interrupt which runs on a higher priority than
* Timer0. This ensures that systick will get interrupted by
* this timer and hence we can test interrupt nesting. */
#define SECOND_TIMER_INDEX 1
/* Frequency of the second timer - This timer is configured at
* a frequency offset of 17 from the systick timer. */
#define SECOND_TIMER_TICK_RATE_HZ ( configTICK_RATE_HZ + 17 )
#define SECOND_TIMER_TICK_DIVISOR ( configCPU_CLOCK_HZ / SECOND_TIMER_TICK_RATE_HZ )
/*-----------------------------------------------------------*/
/* Defined in main_full.c. */
extern BaseType_t xTimerForQueueTestInitialized;
/*-----------------------------------------------------------*/
/* Interrupt handler for timer interrupt. */
#if( SECOND_TIMER_AVAILABLE == 1 )
static void prvTimer2Handler( void *arg );
#endif /* SECOND_TIMER_AVAILABLE */
/*-----------------------------------------------------------*/
void vInitialiseTimerForIntQueueTest( void )
{
unsigned currentCycleCount, firstComparatorValue;
/* Inform the tick hook function that it can access queues now. */
xTimerForQueueTestInitialized = pdTRUE;
#if( SECOND_TIMER_AVAILABLE == 1 )
{
/* Install the interrupt handler for second timer. */
xt_set_interrupt_handler( XCHAL_TIMER1_INTERRUPT, prvTimer2Handler, NULL );
/* Read the current cycle count. */
currentCycleCount = xthal_get_ccount();
/* Calculate time of the first timer interrupt. */
firstComparatorValue = currentCycleCount + SECOND_TIMER_TICK_DIVISOR;
/* Set the comparator. */
xthal_set_ccompare( SECOND_TIMER_INDEX, firstComparatorValue );
/* Enable timer interrupt. */
xt_ints_on( ( 1 << XCHAL_TIMER1_INTERRUPT ) );
}
#endif /* SECOND_TIMER_AVAILABLE */
}
/*-----------------------------------------------------------*/
/*
* Xtensa timers work by comparing a cycle counter with a preset value. Once the match occurs
* an interrupt is generated, and the handler has to set a new cycle count into the comparator.
* To avoid clock drift due to interrupt latency, the new cycle count is computed from the old,
* not the time the interrupt was serviced. However if a timer interrupt is ever serviced more
* than one tick late, it is necessary to process multiple ticks until the new cycle count is
* in the future, otherwise the next timer interrupt would not occur until after the cycle
* counter had wrapped (2^32 cycles later).
do {
ticks++;
old_ccompare = read_ccompare_i();
write_ccompare_i( old_ccompare + divisor );
service one tick;
diff = read_ccount() - old_ccompare;
} while ( diff > divisor );
*/
#if( SECOND_TIMER_AVAILABLE == 1 )
static void prvTimer2Handler( void *arg )
{
unsigned oldComparatorValue, newComparatorValue, currentCycleCount;
/* Unused arguments. */
( void )arg;
do
{
/* Read old comparator value. */
oldComparatorValue = xthal_get_ccompare( SECOND_TIMER_INDEX );
/* Calculate the new comparator value. */
newComparatorValue = oldComparatorValue + SECOND_TIMER_TICK_DIVISOR;
/* Update comparator and clear interrupt. */
xthal_set_ccompare( SECOND_TIMER_INDEX, newComparatorValue );
/* Process. */
portYIELD_FROM_ISR( xSecondTimerHandler() );
/* Ensure comparator update is complete. */
xthal_icache_sync();
/* Read current cycle count to check if we need to process more
* ticks to catch up. */
currentCycleCount = xthal_get_ccount();
} while( ( currentCycleCount - oldComparatorValue ) > SECOND_TIMER_TICK_DIVISOR );
}
#endif /* SECOND_TIMER_AVAILABLE */
/*-----------------------------------------------------------*/

@ -0,0 +1,36 @@
/*
* FreeRTOS Kernel V10.0.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. If you wish to use our Amazon
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#ifndef INT_QUEUE_TIMER_H
#define INT_QUEUE_TIMER_H
void vInitialiseTimerForIntQueueTest( void );
void vTimer2Handler_C( void );
#endif /* INT_QUEUE_TIMER_H */

@ -0,0 +1,181 @@
/*
* FreeRTOS Kernel V10.0.1
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 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 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.
*
*******************************************************************************
*/
/* Standard includes. */
#include <stdio.h>
#include <stdlib.h>
/* FreeRTOS kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
/* This project provides two demo applications. A simple blinky style demo
application, and a more comprehensive test and demo application. The
mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is used to select between the two.
If mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is 1 then the blinky demo will be built.
The blinky demo is implemented and described in main_blinky.c.
If mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is not 1 then the comprehensive test and
demo application will be built. The comprehensive test and demo application is
implemented and described in main_full.c. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0
/*-----------------------------------------------------------*/
/*
* 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.
*/
extern void main_blinky( void );
extern void main_full( void );
/*
* Prototypes for the standard FreeRTOS application hook (callback) functions
* implemented within this file. See http://www.freertos.org/a00016.html .
*/
void vApplicationMallocFailedHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationTickHook( void );
/*
* Only the comprehensive demo uses application hook (callback) functions. See
* http://www.freertos.org/a00016.html for more information.
*/
void vFullDemoTickHookFunction( void );
/*-----------------------------------------------------------*/
int main( void )
{
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{
main_blinky();
}
#else
{
main_full();
}
#endif
return 0;
}
/*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c, heap_2.c or heap_4.c is being used, then the
size of the heap available to pvPortMalloc() is defined by
configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize()
API function can be used to query the size of free heap space that remains
(although it does not provide information on how the remaining heap might be
fragmented). See http://www.freertos.org/a00111.html for more
information. */
vAssertCalled( __LINE__, __FILE__ );
}
/*-----------------------------------------------------------*/
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. This function is
provided as an example only as stack overflow checking does not function
when running the FreeRTOS Windows port. */
vAssertCalled( __LINE__, __FILE__ );
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 )
{
vFullDemoTickHookFunction();
}
#endif /* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY */
}
/*-----------------------------------------------------------*/
void vAssertCalled( unsigned long ulLine, const char * const pcFileName )
{
static BaseType_t xPrinted = pdFALSE;
volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
/* Called if an assertion passed to configASSERT() fails. See
http://www.freertos.org/a00110.html#configASSERT for more information. */
/* Parameters are not used. */
( void ) ulLine;
( void ) pcFileName;
printf( "ASSERT! Line %ld, file %s\r\n", ulLine, pcFileName );
taskENTER_CRITICAL();
{
/* You can step out of this function to debug the assertion by using
the debugger to set ulSetToNonZeroInDebuggerToContinue to a non-zero
value. */
while( ulSetToNonZeroInDebuggerToContinue == 0 )
{
__asm volatile( "NOP" );
__asm volatile( "NOP" );
}
}
taskEXIT_CRITICAL();
}
/*-----------------------------------------------------------*/

@ -0,0 +1,265 @@
/*
* FreeRTOS Kernel V10.0.1
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/******************************************************************************
* NOTE 1: Windows will not be running the FreeRTOS demo threads continuously, so
* do not expect to get real time behaviour from the FreeRTOS Windows port, or
* this demo application. Also, the timing information in the FreeRTOS+Trace
* logs have no meaningful units. See the documentation page for the Windows
* port for further information:
* http://www.freertos.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html
*
* NOTE 2: 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 version. Console output
* is used in place of the normal LED toggling.
*
* NOTE 3: This file only contains the source code that is specific to the
* basic demo. Generic functions, such FreeRTOS hook functions, are defined
* in main.c.
******************************************************************************
*
* main_blinky() creates one queue, one software timer, 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. It uses vTaskDelayUntil() to create a periodic task that sends
* the value 100 to the queue every 200 milliseconds (please read the notes
* above regarding the accuracy of timing under Windows).
*
* The Queue Send Software Timer:
* The timer is an auto-reload timer with a period of two seconds. The timer's
* callback function writes the value 200 to the queue. The callback function
* is implemented by prvQueueSendTimerCallback() within this file.
*
* The Queue Receive Task:
* The queue receive task is implemented by the prvQueueReceiveTask() function
* in this file. prvQueueReceiveTask() waits for data to arrive on the queue.
* When data is received, the task checks the value of the data, then outputs a
* message to indicate if the data came from the queue send task or the queue
* send software timer.
*
* Expected Behaviour:
* - The queue send task writes to the queue every 200ms, so every 200ms the
* queue receive task will output a message indicating that data was received
* on the queue from the queue send task.
* - The queue send software timer has a period of two seconds, and is reset
* each time a key is pressed. So if two seconds expire without a key being
* pressed then the queue receive task will output a message indicating that
* data was received on the queue from the queue send software timer.
*
* NOTE: Console input and output relies on Windows system calls, which can
* interfere with the execution of the FreeRTOS Windows port. This demo only
* uses Windows system call occasionally. Heavier use of Windows system calls
* can crash the port.
*/
/* Standard includes. */
#include <stdio.h>
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.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 times are converted from
milliseconds to ticks using the pdMS_TO_TICKS() macro. */
#define mainTASK_SEND_FREQUENCY_MS pdMS_TO_TICKS( 200UL )
#define mainTIMER_SEND_FREQUENCY_MS pdMS_TO_TICKS( 2000UL )
/* The number of items the queue can hold at once. */
#define mainQUEUE_LENGTH ( 2 )
/* The values sent to the queue receive task from the queue send task and the
queue send software timer respectively. */
#define mainVALUE_SENT_FROM_TASK ( 100UL )
#define mainVALUE_SENT_FROM_TIMER ( 200UL )
/*-----------------------------------------------------------*/
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
/*
* The callback function executed when the software timer expires.
*/
static void prvQueueSendTimerCallback( TimerHandle_t xTimerHandle );
/*-----------------------------------------------------------*/
/* The queue used by both tasks. */
static QueueHandle_t xQueue = NULL;
/* A software timer that is started from the tick hook. */
static TimerHandle_t xTimer = NULL;
/*-----------------------------------------------------------*/
/*** SEE THE COMMENTS AT THE TOP OF THIS FILE ***/
void main_blinky( void )
{
const TickType_t xTimerPeriod = mainTIMER_SEND_FREQUENCY_MS;
/* 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, /* The size of the stack to allocate to the task. */
NULL, /* The parameter passed to the task - not used in this simple 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, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Create the software timer, but don't start it yet. */
xTimer = xTimerCreate( "Timer", /* The text name assigned to the software timer - for debug only as it is not used by the kernel. */
xTimerPeriod, /* The period of the software timer in ticks. */
pdTRUE, /* xAutoReload is set to pdTRUE. */
NULL, /* The timer's ID is not used. */
prvQueueSendTimerCallback );/* The function executed when the timer expires. */
if( xTimer != NULL )
{
xTimerStart( xTimer, 0 );
}
/* 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 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 prvQueueSendTask( void *pvParameters )
{
TickType_t xNextWakeTime;
const TickType_t xBlockTime = mainTASK_SEND_FREQUENCY_MS;
const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TASK;
/* Prevent the compiler warning about the 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.
The block time is specified in ticks, pdMS_TO_TICKS() was used to
convert a time specified in milliseconds into a time specified in ticks.
While in the Blocked state this task will not consume any CPU time. */
vTaskDelayUntil( &xNextWakeTime, xBlockTime );
/* Send to the queue - causing the queue receive task to unblock and
write to the console. 0 is used as the block time so the send operation
will not block - it shouldn't need to block as the queue should always
have at least one space at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U );
}
}
/*-----------------------------------------------------------*/
static void prvQueueSendTimerCallback( TimerHandle_t xTimerHandle )
{
const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TIMER;
/* This is the software timer callback function. The software timer has a
period of two seconds and is reset each time a key is pressed. This
callback function will execute if the timer expires, which will only happen
if a key is not pressed for two seconds. */
/* Avoid compiler warnings resulting from the unused parameter. */
( void ) xTimerHandle;
/* Send to the queue - causing the queue receive task to unblock and
write out a message. This function is called from the timer/daemon task, so
must not block. Hence the block time is set to 0. */
xQueueSend( xQueue, &ulValueToSend, 0U );
}
/*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters )
{
uint32_t ulReceivedValue;
/* Prevent the compiler warning about the unused parameter. */
( void ) pvParameters;
for( ;; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. It will not use any CPU time while it is in the
Blocked state. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but
is it an expected value? Normally calling printf() from a task is not
a good idea. Here there is lots of stack space and only one task is
using console IO so it is ok. However, note the comments at the top of
this file about the risks of making Windows system calls (such as
console output) from a FreeRTOS task. */
if( ulReceivedValue == mainVALUE_SENT_FROM_TASK )
{
printf( "Message received from task\r\n" );
}
else if( ulReceivedValue == mainVALUE_SENT_FROM_TIMER )
{
printf( "Message received from software timer\r\n" );
}
else
{
printf( "Unexpected message\r\n" );
}
fflush( stdout );
}
}
/*-----------------------------------------------------------*/

@ -0,0 +1,437 @@
/*
* FreeRTOS Kernel V10.0.1
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/*
* main() creates all the demo application tasks, 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:
*
* "Check" task - This only executes every five seconds but has a high priority
* to ensure it gets processor time. Its main function is to check that all the
* standard demo tasks are still operational. While no errors have been
* discovered the check task will print out "OK" and the current simulated tick
* time. If an error is discovered in the execution of a task then the check
* task will print out an appropriate error message.
*
*/
/* Standard includes. */
#include <stdio.h>
#include <stdlib.h>
/* Kernel includes. */
#include <FreeRTOS.h>
#include <task.h>
#include <queue.h>
#include <timers.h>
#include <semphr.h>
/* Standard demo includes. */
#include "BlockQ.h"
#include "integer.h"
#include "semtest.h"
#include "PollQ.h"
#include "GenQTest.h"
#include "QPeek.h"
#include "recmutex.h"
#include "flop.h"
#include "TimerDemo.h"
#include "countsem.h"
#include "death.h"
#include "QueueSet.h"
#include "QueueOverwrite.h"
#include "EventGroupsDemo.h"
#include "IntSemTest.h"
#include "TaskNotify.h"
#include "QueueSetPolling.h"
#include "StaticAllocation.h"
#include "blocktim.h"
#include "AbortDelay.h"
#include "MessageBufferDemo.h"
#include "StreamBufferDemo.h"
#include "StreamBufferInterrupt.h"
/* Priorities at which the tasks are created. */
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainQUEUE_OVERWRITE_PRIORITY ( tskIDLE_PRIORITY )
#define mainTIMER_TEST_PERIOD ( 50 )
/* Parameters that are passed into the register check tasks solely for the
purpose of ensuring parameters are passed into tasks correctly. */
#define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 )
#define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 )
/* Whether or not to enable interrupt queue tests. */
#define mainENABLE_INT_QUEUE_TESTS ( 0 )
/* The task that periodically checks that all the standard demo tasks are
* still executing and error free.
*/
static void prvCheckTask( void *pvParameters );
/* Tasks that implement register tests. */
static void prvRegTest1Task( void *pvParameters );
static void prvRegTest2Task( void *pvParameters );
/* Functions implemented in assembly file regtest_xtensa.S. */
extern void vRegTest1( void );
extern void vRegTest2( void );
/*-----------------------------------------------------------*/
/* The variable into which error messages are latched. */
static char *pcStatusMessage = "No errors";
/* The following two variables are used to communicate the status of the
register check tasks to the check task. If the variables keep incrementing,
then the register check tasks have not discovered any errors. If a variable
stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1Counter = 0UL, ulRegTest2Counter = 0UL;
/* The following variable is used to communicate whether the timers for the
IntQueue tests have been Initialized. This is needed to ensure that the queues
are accessed from the tick hook only after they have been created in the
interrupt queue test. */
volatile BaseType_t xTimerForQueueTestInitialized = pdFALSE;
/*-----------------------------------------------------------*/
int main_full( void )
{
/* Start the check task as described at the top of this file. */
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
#if( mainENABLE_INT_QUEUE_TESTS == 0 )
{
/* Create the standard demo tasks. */
vStartTaskNotifyTask();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
vStartQueuePeekTasks();
vStartMathTasks( mainFLOP_TASK_PRIORITY );
vStartRecursiveMutexTasks();
vStartCountingSemaphoreTasks();
vStartQueueSetTasks();
vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY );
vStartEventGroupTasks();
vStartInterruptSemaphoreTasks();
vStartQueueSetPollingTask();
vCreateBlockTimeTasks();
#if( configUSE_PREEMPTION != 0 )
{
/* Don't expect these tasks to pass when preemption is not used. */
vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
}
#endif
vCreateAbortDelayTasks();
vStartMessageBufferTasks( configMINIMAL_STACK_SIZE );
vStartStreamBufferTasks();
vStartStreamBufferInterruptDemo();
/* Create the register check tasks, as described at the top of this file */
xTaskCreate( prvRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_1_PARAMETER, tskIDLE_PRIORITY, NULL );
xTaskCreate( prvRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL );
/* The suicide tasks must be created last as they need to know how many
tasks were running prior to their creation. This then allows them to
ascertain whether or not the correct/expected number of tasks are running at
any given time. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
}
#else /* mainENABLE_INT_QUEUE_TESTS */
{
/* Start interrupt queue test tasks. */
vStartInterruptQueueTasks();
}
#endif /* mainENABLE_INT_QUEUE_TESTS */
/* Start the scheduler itself. */
vTaskStartScheduler();
/* Should never get here unless there was not enough heap space to create
the idle and other system tasks. */
return 0;
}
/*-----------------------------------------------------------*/
static void prvCheckTask( void *pvParameters )
{
TickType_t xNextWakeTime;
const TickType_t xCycleFrequency = pdMS_TO_TICKS( 5000UL );
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
/* Just to remove compiler warning. */
( 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, xCycleFrequency );
#if( mainENABLE_INT_QUEUE_TESTS == 0 )
{
/* Check the standard demo tasks are running without error. */
#if( configUSE_PREEMPTION != 0 )
{
/* These tasks are only created when preemption is used. */
if( xAreTimerDemoTasksStillRunning( xCycleFrequency ) != pdTRUE )
{
pcStatusMessage = "Error: TimerDemo";
}
}
#endif
if( xAreTaskNotificationTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: Notification";
}
else if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: BlockQueue";
}
else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: SemTest";
}
else if( xArePollingQueuesStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: PollQueue";
}
else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: IntMath";
}
else if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: GenQueue";
}
else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: QueuePeek";
}
else if( xAreMathsTaskStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Flop";
}
else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: RecMutex";
}
else if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: CountSem";
}
else if( xAreQueueSetTasksStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Queue set";
}
else if( xIsQueueOverwriteTaskStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Queue overwrite";
}
else if( xAreEventGroupTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: EventGroup";
}
else if( xAreInterruptSemaphoreTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: IntSem";
}
else if( xAreQueueSetPollTasksStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Queue set polling";
}
else if( xAreBlockTimeTestTasksStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Block time";
}
else if( xAreAbortDelayTestTasksStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Abort delay";
}
else if( xAreMessageBufferTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: MessageBuffer";
}
else if( xAreStreamBufferTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: StreamBuffer";
}
else if( xIsInterruptStreamBufferDemoStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Stream buffer interrupt";
}
else if( xIsCreateTaskStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: Death";
}
else if( ulLastRegTest1Value == ulRegTest1Counter )
{
pcStatusMessage = "Error: Reg Test 1";
}
else if( ulLastRegTest2Value == ulRegTest2Counter )
{
pcStatusMessage = "Error: Reg Test 2";
}
/* Update register test counters. */
ulLastRegTest1Value = ulRegTest1Counter;
ulLastRegTest2Value = ulRegTest2Counter;
}
#else /* mainENABLE_INT_QUEUE_TESTS */
{
if( xAreIntQueueTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: IntQueue";
}
}
#endif /* mainENABLE_INT_QUEUE_TESTS */
/* This is the only task that uses stdout so its ok to call printf()
directly. */
printf( "%s - tick count %zu - free heap %zu - min free heap %zu\r\n", pcStatusMessage,
xTaskGetTickCount(),
xPortGetFreeHeapSize(),
xPortGetMinimumEverFreeHeapSize() );
}
}
/*-----------------------------------------------------------*/
/* Called by vApplicationTickHook(), which is defined in main.c. */
void vFullDemoTickHookFunction( void )
{
TaskHandle_t xTimerTask;
#if( mainENABLE_INT_QUEUE_TESTS == 0 )
{
/* Exercise using task notifications from an interrupt. */
xNotifyTaskFromISR();
/* Write to a queue that is in use as part of the queue set demo to
* demonstrate using queue sets from an ISR. */
vQueueSetAccessQueueSetFromISR();
/* Call the periodic queue overwrite from ISR demo. */
vQueueOverwritePeriodicISRDemo();
/* Exercise event groups from interrupts. */
vPeriodicEventGroupsProcessing();
/* Exercise giving mutexes from an interrupt. */
vInterruptSemaphorePeriodicTest();
/* Queue set access from interrupt. */
vQueueSetPollingInterruptAccess();
/* Call the periodic timer test, which tests the timer API functions that
can be called from an ISR. */
#if( configUSE_PREEMPTION != 0 )
{
/* Only created when preemption is used. */
vTimerPeriodicISRTests();
}
#endif
/* Writes to stream buffer byte by byte to test the stream buffer trigger
level functionality. */
vPeriodicStreamBufferProcessing();
/* Writes a string to a string buffer four bytes at a time to demonstrate
a stream being sent from an interrupt to a task. */
vBasicStreamBufferSendFromISR();
}
#else /* mainENABLE_INT_QUEUE_TESTS */
{
/* Access queues from interrupt. Make sure to access after the queues have
been created. */
if( xTimerForQueueTestInitialized == pdTRUE )
{
portYIELD_FROM_ISR( xFirstTimerHandler() );
}
}
#endif /* mainENABLE_INT_QUEUE_TESTS */
}
/*-----------------------------------------------------------*/
static void prvRegTest1Task( void *pvParameters )
{
/* Although the regtest task is written in assembly, its entry point is
written in C for convenience of checking the task parameter is being passed
in correctly. */
if( pvParameters == mainREG_TEST_TASK_1_PARAMETER )
{
/* Start the part of the test that is written in assembly. */
vRegTest1();
}
/* The following line will only execute if the task parameter is found to
be incorrect. The check task will detect that the regtest loop counter is
not being incremented and flag an error. */
vTaskDelete( NULL );
}
/*-----------------------------------------------------------*/
static void prvRegTest2Task( void *pvParameters )
{
/* Although the regtest task is written in assembly, its entry point is
written in C for convenience of checking the task parameter is being passed
in correctly. */
if( pvParameters == mainREG_TEST_TASK_2_PARAMETER )
{
/* Start the part of the test that is written in assembly. */
vRegTest2();
}
/* The following line will only execute if the task parameter is found to
be incorrect. The check task will detect that the regtest loop counter is
not being incremented and flag an error. */
vTaskDelete( NULL );
}
/*-----------------------------------------------------------*/

@ -0,0 +1,219 @@
/*
* FreeRTOS Kernel V10.0.1
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#include "FreeRTOSConfig.h"
//#include "ISR_Support.h"
.extern ulRegTest1Counter
.extern ulRegTest2Counter
.extern vPortYield
.global vRegTest1
.global vRegTest2
.text
.align 4
/*-----------------------------------------------------------*/
vRegTest1:
/* Set initial values into the general purpose registers. */
/* a0 = return address, a1 = stack pointer. */
#ifdef __XTENSA_WINDOWED_ABI__
entry a1, 64
s32i a0, a1, 0 /* Save return address */
#else
addi a1, a1, -64
s32i a0, a1, 0 /* Save return address */
s32i a12, a1, 4 /* Save callee-saved regs if call0 ABI */
s32i a13, a1, 8
s32i a14, a1, 12
s32i a15, a1, 16
#endif
movi a2, 0x11111111
movi a3, 0x22222222
movi a4, 0x33333333
movi a5, 0x44444444
movi a6, 0x55555555
movi a7, 0x66666666
movi a8, 0x77777777
movi a9, 0x88888888
movi a10, 0x99999999
movi a11, 0xaaaaaaaa
movi a12, 0xbbbbbbbb
movi a13, 0xcccccccc
movi a14, 0xdddddddd
movi a15, 0xeeeeeeee
_RegTest1Loop:
/* Loop checking the values originally loaded into the general purpose
registers remain through the life of the task. */
movi a0, 0x11111111
bne a0, a2, _RegTest1Error
movi a0, 0x22222222
bne a0, a3, _RegTest1Error
movi a0, 0x33333333
bne a0, a4, _RegTest1Error
movi a0, 0x44444444
bne a0, a5, _RegTest1Error
movi a0, 0x55555555
bne a0, a6, _RegTest1Error
movi a0, 0x66666666
bne a0, a7, _RegTest1Error
movi a0, 0x77777777
bne a0, a8, _RegTest1Error
movi a0, 0x88888888
bne a0, a9, _RegTest1Error
movi a0, 0x99999999
bne a0, a10, _RegTest1Error
movi a0, 0xaaaaaaaa
bne a0, a11, _RegTest1Error
movi a0, 0xbbbbbbbb
bne a0, a12, _RegTest1Error
movi a0, 0xcccccccc
bne a0, a13, _RegTest1Error
movi a0, 0xdddddddd
bne a0, a14, _RegTest1Error
movi a0, 0xeeeeeeee
bne a0, a15, _RegTest1Error
/* Incrememnt the loop counter to prove this task has not gone into the
error null loop. */
s32i a2, a1, 20
movi a2, ulRegTest1Counter
l32i a0, a2, 0
addi a0, a0, 1
s32i a0, a2, 0
l32i a2, a1, 20
/* Loop again. */
j _RegTest1Loop
_RegTest1Error:
.L1:
j .L1
.align 4
/*-----------------------------------------------------------*/
vRegTest2:
/* Set initial values into the general purpose registers. */
/* a0 = return address, a1 = stack pointer. */
#ifdef __XTENSA_WINDOWED_ABI__
entry a1, 64
s32i a0, a1, 0 /* Save return address */
#else
addi a1, a1, -64
s32i a0, a1, 0 /* Save return address */
s32i a12, a1, 4 /* Save callee-saved regs if call0 ABI */
s32i a13, a1, 8
s32i a14, a1, 12
s32i a15, a1, 16
#endif
_ReInit:
movi a2, 0x01010101
movi a3, 0x02020202
movi a4, 0x03030303
movi a5, 0x04040404
movi a6, 0x05050505
movi a7, 0x06060606
movi a8, 0x07070707
movi a9, 0x08080808
movi a10, 0x09090909
movi a11, 0x0a0a0a0a
movi a12, 0x0b0b0b0b
movi a13, 0x0c0c0c0c
movi a14, 0x0d0d0d0d
movi a15, 0x0e0e0e0e
_RegTest2Loop:
/* Loop checking the values originally loaded into the general purpose
registers remain through the life of the task. */
movi a0, 0x01010101
bne a0, a2, _RegTest1Error
movi a0, 0x02020202
bne a0, a3, _RegTest1Error
movi a0, 0x03030303
bne a0, a4, _RegTest1Error
movi a0, 0x04040404
bne a0, a5, _RegTest1Error
movi a0, 0x05050505
bne a0, a6, _RegTest1Error
movi a0, 0x06060606
bne a0, a7, _RegTest1Error
movi a0, 0x07070707
bne a0, a8, _RegTest1Error
movi a0, 0x08080808
bne a0, a9, _RegTest1Error
movi a0, 0x09090909
bne a0, a10, _RegTest1Error
movi a0, 0x0a0a0a0a
bne a0, a11, _RegTest1Error
movi a0, 0x0b0b0b0b
bne a0, a12, _RegTest1Error
movi a0, 0x0c0c0c0c
bne a0, a13, _RegTest1Error
movi a0, 0x0d0d0d0d
bne a0, a14, _RegTest1Error
movi a0, 0x0e0e0e0e
bne a0, a15, _RegTest1Error
/* Force a yield from one of the reg test tasks to increase coverage. */
/* IMPORTANT: this call will trash some number of registers. Branch */
/* to _ReInit to set things up again. */
#ifdef __XTENSA_WINDOWED_ABI__
call8 vPortYield
#else
call0 vPortYield
#endif
/* Increment the loop counter to prove this task has not gone into the
error null loop. */
s32i a2, a1, 20
movi a2, ulRegTest2Counter
l32i a0, a2, 0
addi a0, a0, 1
s32i a0, a2, 0
l32i a2, a1, 20
/* Loop again. */
j _ReInit /* See comments above */
/* j _RegTest2Loop */
_RegTest2Error:
.L2:
j .L2

@ -0,0 +1,98 @@
### Makefile to build the FreeRTOS library ###
# Build target (options: sim, board)
TARGET = sim
SMALL =
# Tools
CC = xt-xcc
AS = xt-xcc
AR = xt-ar
XT_CORE = $(patsubst %-params,%,$(notdir $(shell xt-xcc --show-config=core)))
CONFIGDIR = $(shell xt-xcc --show-config=config)
# For platform-specific commands
include $(CONFIGDIR)/misc/hostenv.mk
# Source code and build locations
SRCROOT = $(subst /,$(S),$(CURDIR))
TSTROOT = $(abspath $(SRCROOT)$(S)..$(S)..$(S)..$(S)..$(S)..$(S)demos$(S)cadence$(S)sim$(SMALL))
BLDROOT = $(TSTROOT)$(S)build
BLDDIR = $(BLDROOT)$(S)$(XT_CORE)
FR_SRCDIR = $(abspath $(SRCROOT)$(S)..$(S)..$(S)..)
FR_SRCDIR2 = $(FR_SRCDIR)$(S)portable$(S)MemMang
XT_SRCDIR = $(SRCROOT)
vpath %.c $(FR_SRCDIR) $(FR_SRCDIR2) $(XT_SRCDIR)
vpath %.S $(XT_SRCDIR)
# File lists
FR_C_FILES = $(notdir $(wildcard $(FR_SRCDIR)/*.c)) $(notdir $(wildcard $(FR_SRCDIR2)/*.c))
XT_C_FILES = $(notdir $(wildcard $(XT_SRCDIR)/*.c))
XT_S_FILES = $(notdir $(wildcard $(XT_SRCDIR)/*.S))
# List of all .o files that will go into the library
LIB_C_O = $(patsubst %.c,%.o,$(XT_C_FILES) $(FR_C_FILES))
LIB_S_O = $(patsubst %.S,%.o,$(XT_S_FILES))
LIB_O_LIST = $(addprefix $(BLDDIR)/,$(LIB_C_O) $(LIB_S_O))
# Output files
OSLIB = $(BLDDIR)$(S)libfreertos.a
# Build options
ifeq ($(TARGET),sim)
DFLAGS = -DXT_SIMULATOR
endif
ifeq ($(TARGET),board)
DFLAGS = -DXT_BOARD
endif
IFLAGS = \
-I$(FR_SRCDIR)$(S)..$(S)include -I$(FR_SRCDIR)$(S)..$(S)include$(S)private \
-I$(XT_SRCDIR) -I$(TSTROOT)$(S)common$(S)config_files -I$(BLDDIR)
CFLAGS = -O2 -g
CCFLAGS = $(CFLAGS) -Wall -mno-coproc -mlongcalls -ffunction-sections -mno-l32r-flix $(DFLAGS)
ASFLAGS = $(CCFLAGS)
# Include dependency rules (generated using -MD)
-include $(wildcard $(BLDDIR)/*.d)
# Targets
all : mkdir $(OSLIB)
mkdir : $(BLDDIR)/.mkdir
$(BLDDIR)/.mkdir :
@$(MKPATH) $(BLDDIR)
@echo "" > $@
-$(CP) $(CONFIGDIR)/xtensa-elf/include/sys/reent.h $(BLDDIR)/reent.h
$(OSLIB) : $(LIB_O_LIST)
$(AR) -rs $@ $^
$(BLDDIR)/%.o : %.c
$(CC) $(CCFLAGS) $(IFLAGS) -MD -MF $(subst .o,.d,$@) -c -o $@ $<
$(BLDDIR)/%.o : %.S
$(CC) $(ASFLAGS) $(IFLAGS) -MD -MF $(subst .o,.d,$@) -c -o $@ $<
clean :
$(RM_R) $(BLDDIR)
clean_all :
$(RM_R) $(BLDROOT)
.PHONY : all mkdir clean clean_all

@ -0,0 +1,261 @@
/*
FreeRTOS V9.0.0 - Copyright (C) 2016 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!
*/
/*******************************************************************************
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
*/
#include <stdlib.h>
#include <xtensa/config/core.h>
#include "xtensa_rtos.h"
#include "FreeRTOS.h"
#include "task.h"
/* Defined in portasm.h */
extern void _frxt_tick_timer_init(void);
/* Defined in xtensa_context.S */
extern void _xt_coproc_init(void);
/*-----------------------------------------------------------*/
/* We require the address of the pxCurrentTCB variable, but don't want to know
any details of its type. */
typedef void TCB_t;
extern volatile TCB_t * volatile pxCurrentTCB;
unsigned port_xSchedulerRunning = 0; // Duplicate of inaccessible xSchedulerRunning; needed at startup to avoid counting nesting
unsigned port_interruptNesting = 0; // Interrupt nesting level
/*-----------------------------------------------------------*/
// User exception dispatcher when exiting
void _xt_user_exit(void);
/*
* Stack initialization
*/
#if portUSING_MPU_WRAPPERS
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged )
#else
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
#endif
{
StackType_t *sp, *tp;
XtExcFrame *frame;
#if XCHAL_CP_NUM > 0
uint32_t *p;
#endif
/* Create interrupt stack frame aligned to 16 byte boundary */
sp = (StackType_t *) (((UBaseType_t)(pxTopOfStack + 1) - XT_CP_SIZE - XT_STK_FRMSZ) & ~0xf);
/* Clear the entire frame (do not use memset() because we don't depend on C library) */
for (tp = sp; tp <= pxTopOfStack; ++tp)
*tp = 0;
frame = (XtExcFrame *) sp;
/* Explicitly initialize certain saved registers */
frame->pc = (UBaseType_t) pxCode; /* task entrypoint */
frame->a0 = 0; /* to terminate GDB backtrace */
frame->a1 = (UBaseType_t) sp + XT_STK_FRMSZ; /* physical top of stack frame */
frame->exit = (UBaseType_t) _xt_user_exit; /* user exception exit dispatcher */
/* Set initial PS to int level 0, EXCM disabled ('rfe' will enable), user mode. */
/* Also set entry point argument parameter. */
#ifdef __XTENSA_CALL0_ABI__
frame->a2 = (UBaseType_t) pvParameters;
frame->ps = PS_UM | PS_EXCM;
#else
/* + for windowed ABI also set WOE and CALLINC (pretend task was 'call4'd). */
frame->a6 = (UBaseType_t) pvParameters;
frame->ps = PS_UM | PS_EXCM | PS_WOE | PS_CALLINC(1);
#endif
#ifdef XT_USE_SWPRI
/* Set the initial virtual priority mask value to all 1's. */
frame->vpri = 0xFFFFFFFF;
#endif
#if XCHAL_CP_NUM > 0
/* Init the coprocessor save area (see xtensa_context.h) */
/* No access to TCB here, so derive indirectly. Stack growth is top to bottom.
* //p = (uint32_t *) xMPUSettings->coproc_area;
*/
p = (uint32_t *)(((uint32_t) pxTopOfStack - XT_CP_SIZE) & ~0xf);
p[0] = 0;
p[1] = 0;
p[2] = (((uint32_t) p) + 12 + XCHAL_TOTAL_SA_ALIGN - 1) & -XCHAL_TOTAL_SA_ALIGN;
#endif
return sp;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the Xtensa port will get stopped. If required simply
disable the tick interrupt here. */
}
/*-----------------------------------------------------------*/
BaseType_t xPortStartScheduler( void )
{
// Interrupts are disabled at this point and stack contains PS with enabled interrupts when task context is restored
#if XCHAL_CP_NUM > 0
/* Initialize co-processor management for tasks. Leave CPENABLE alone. */
_xt_coproc_init();
#endif
/* Init the tick divisor value */
_xt_tick_divisor_init();
/* Setup the hardware to generate the tick. */
_frxt_tick_timer_init();
#if XT_USE_THREAD_SAFE_CLIB
// Init C library
vPortClibInit();
#endif
port_xSchedulerRunning = 1;
// Cannot be directly called from C; never returns
__asm__ volatile ("call0 _frxt_dispatch\n");
/* Should not get here. */
return pdTRUE;
}
/*-----------------------------------------------------------*/
BaseType_t xPortSysTickHandler( void )
{
BaseType_t ret;
unsigned interruptMask;
portbenchmarkIntLatency();
/* Interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY must be
* disabled before calling xTaskIncrementTick as it access the
* kernel lists. */
interruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
{
ret = xTaskIncrementTick();
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( interruptMask );
portYIELD_FROM_ISR( ret );
return ret;
}
/*-----------------------------------------------------------*/
/*
* Used to set coprocessor area in stack. Current hack is to reuse MPU pointer for coprocessor area.
*/
#if portUSING_MPU_WRAPPERS
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth )
{
#if XCHAL_CP_NUM > 0
xMPUSettings->coproc_area = (StackType_t*)((((uint32_t)(pxBottomOfStack + ulStackDepth - 1)) - XT_CP_SIZE ) & ~0xf);
/* NOTE: we cannot initialize the coprocessor save area here because FreeRTOS is going to
* clear the stack area after we return. This is done in pxPortInitialiseStack().
*/
#endif
}
#endif
/*-----------------------------------------------------------*/

@ -0,0 +1,597 @@
/*
//-----------------------------------------------------------------------------
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//-----------------------------------------------------------------------------
*/
#include "xtensa_rtos.h"
#define TOPOFSTACK_OFFS 0x00 /* StackType_t *pxTopOfStack */
#define CP_TOPOFSTACK_OFFS 0x04 /* xMPU_SETTINGS.coproc_area */
.extern pxCurrentTCB
/*
*******************************************************************************
* Interrupt stack. The size of the interrupt stack is determined by the config
* parameter "configISR_STACK_SIZE" in FreeRTOSConfig.h
*******************************************************************************
*/
.data
.align 16
.global port_IntStack
port_IntStack:
.space configISR_STACK_SIZE
port_IntStackTop:
.word 0
port_switch_flag:
.word 0
.text
/*
*******************************************************************************
* _frxt_setup_switch
* void _frxt_setup_switch(void);
*
* Sets an internal flag indicating that a task switch is required on return
* from interrupt handling.
*
*******************************************************************************
*/
.global _frxt_setup_switch
.type _frxt_setup_switch,@function
.align 4
_frxt_setup_switch:
ENTRY(16)
movi a2, port_switch_flag
movi a3, 1
s32i a3, a2, 0
RET(16)
/*
*******************************************************************************
* _frxt_int_enter
* void _frxt_int_enter(void)
*
* Implements the Xtensa RTOS porting layer's XT_RTOS_INT_ENTER function for
* freeRTOS. Saves the rest of the interrupt context (not already saved).
* May only be called from assembly code by the 'call0' instruction, with
* interrupts disabled.
* See the detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
*
*******************************************************************************
*/
.globl _frxt_int_enter
.type _frxt_int_enter,@function
.align 4
_frxt_int_enter:
/* Save a12-13 in the stack frame as required by _xt_context_save. */
s32i a12, a1, XT_STK_A12
s32i a13, a1, XT_STK_A13
/* Save return address in a safe place (free a0). */
mov a12, a0
/* Save the rest of the interrupted context (preserves A12-13). */
call0 _xt_context_save
/*
Save interrupted task's SP in TCB only if not nesting.
Manage nesting directly rather than call the generic IntEnter()
(in windowed ABI we can't call a C function here anyway because PS.EXCM is still set).
*/
movi a2, port_xSchedulerRunning
movi a3, port_interruptNesting
l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */
beqz a2, 1f /* scheduler not running, no tasks */
l32i a2, a3, 0 /* a2 = port_interruptNesting */
addi a2, a2, 1 /* increment nesting count */
s32i a2, a3, 0 /* save nesting count */
bnei a2, 1, .Lnested /* !=0 before incr, so nested */
movi a2, pxCurrentTCB
l32i a2, a2, 0 /* a2 = current TCB */
beqz a2, 1f
s32i a1, a2, TOPOFSTACK_OFFS /* pxCurrentTCB->pxTopOfStack = SP */
movi a1, port_IntStackTop /* a1 = top of intr stack */
.Lnested:
1:
mov a0, a12 /* restore return addr and return */
ret
/*
*******************************************************************************
* _frxt_int_exit
* void _frxt_int_exit(void)
*
* Implements the Xtensa RTOS porting layer's XT_RTOS_INT_EXIT function for
* FreeRTOS. If required, calls vPortYieldFromInt() to perform task context
* switching, restore the (possibly) new task's context, and return to the
* exit dispatcher saved in the task's stack frame at XT_STK_EXIT.
* May only be called from assembly code by the 'call0' instruction. Does not
* return to caller.
* See the description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
*
*******************************************************************************
*/
.globl _frxt_int_exit
.type _frxt_int_exit,@function
.align 4
_frxt_int_exit:
movi a2, port_xSchedulerRunning
movi a3, port_interruptNesting
rsil a0, XCHAL_EXCM_LEVEL /* lock out interrupts */
l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */
beqz a2, .Lnoswitch /* scheduler not running, no tasks */
l32i a2, a3, 0 /* a2 = port_interruptNesting */
addi a2, a2, -1 /* decrement nesting count */
s32i a2, a3, 0 /* save nesting count */
bnez a2, .Lnesting /* !=0 after decr so still nested */
movi a2, pxCurrentTCB
l32i a2, a2, 0 /* a2 = current TCB */
beqz a2, 1f /* no task ? go to dispatcher */
l32i a1, a2, TOPOFSTACK_OFFS /* SP = pxCurrentTCB->pxTopOfStack */
movi a2, port_switch_flag /* address of switch flag */
l32i a3, a2, 0 /* a3 = port_switch_flag */
beqz a3, .Lnoswitch /* flag = 0 means no switch reqd */
movi a3, 0
s32i a3, a2, 0 /* zero out the flag for next time */
1:
/*
Call0 ABI callee-saved regs a12-15 need to be saved before possible preemption.
However a12-13 were already saved by _frxt_int_enter().
*/
#ifdef __XTENSA_CALL0_ABI__
s32i a14, a1, XT_STK_A14
s32i a15, a1, XT_STK_A15
#endif
#ifdef __XTENSA_CALL0_ABI__
call0 vPortYieldFromInt /* call dispatch inside the function; never returns */
#else
call4 vPortYieldFromInt /* this one returns */
call0 _frxt_dispatch /* tail-call dispatcher */
/* Never returns here. */
#endif
.Lnoswitch:
/*
If we came here then about to resume the interrupted task.
*/
.Lnesting:
/*
We come here only if there was no context switch, that is if this
is a nested interrupt, or the interrupted task was not preempted.
In either case there's no need to load the SP.
*/
/* Restore full context from interrupt stack frame */
call0 _xt_context_restore
/*
Must return via the exit dispatcher corresponding to the entrypoint from which
this was called. Interruptee's A0, A1, PS, PC are restored and the interrupt
stack frame is deallocated in the exit dispatcher.
*/
l32i a0, a1, XT_STK_EXIT
ret
/*
**********************************************************************************************************
* _frxt_timer_int
* void _frxt_timer_int(void)
*
* Implements the Xtensa RTOS porting layer's XT_RTOS_TIMER_INT function for FreeRTOS.
* Called every timer interrupt.
* Manages the tick timer and calls xPortSysTickHandler() every tick.
* See the detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
*
* Callable from C (obeys ABI conventions). Implemented in assmebly code for performance.
*
**********************************************************************************************************
*/
.globl _frxt_timer_int
.type _frxt_timer_int,@function
.align 4
_frxt_timer_int:
/*
Xtensa timers work by comparing a cycle counter with a preset value. Once the match occurs
an interrupt is generated, and the handler has to set a new cycle count into the comparator.
To avoid clock drift due to interrupt latency, the new cycle count is computed from the old,
not the time the interrupt was serviced. However if a timer interrupt is ever serviced more
than one tick late, it is necessary to process multiple ticks until the new cycle count is
in the future, otherwise the next timer interrupt would not occur until after the cycle
counter had wrapped (2^32 cycles later).
do {
ticks++;
old_ccompare = read_ccompare_i();
write_ccompare_i( old_ccompare + divisor );
service one tick;
diff = read_ccount() - old_ccompare;
} while ( diff > divisor );
*/
ENTRY(16)
.L_xt_timer_int_catchup:
/* Update the timer comparator for the next tick. */
#ifdef XT_CLOCK_FREQ
movi a2, XT_TICK_DIVISOR /* a2 = comparator increment */
#else
movi a3, _xt_tick_divisor
l32i a2, a3, 0 /* a2 = comparator increment */
#endif
rsr a3, XT_CCOMPARE /* a3 = old comparator value */
add a4, a3, a2 /* a4 = new comparator value */
wsr a4, XT_CCOMPARE /* update comp. and clear interrupt */
esync
#ifdef __XTENSA_CALL0_ABI__
/* Preserve a2 and a3 across C calls. */
s32i a2, sp, 4
s32i a3, sp, 8
#endif
/* Call the FreeRTOS tick handler (see port.c). */
#ifdef __XTENSA_CALL0_ABI__
call0 xPortSysTickHandler
#else
call4 xPortSysTickHandler
#endif
#ifdef __XTENSA_CALL0_ABI__
/* Restore a2 and a3. */
l32i a2, sp, 4
l32i a3, sp, 8
#endif
/* Check if we need to process more ticks to catch up. */
esync /* ensure comparator update complete */
rsr a4, CCOUNT /* a4 = cycle count */
sub a4, a4, a3 /* diff = ccount - old comparator */
blt a2, a4, .L_xt_timer_int_catchup /* repeat while diff > divisor */
RET(16)
/*
**********************************************************************************************************
* _frxt_tick_timer_init
* void _frxt_tick_timer_init(void)
*
* Initialize timer and timer interrrupt handler (_xt_tick_divisor_init() has already been been called).
* Callable from C (obeys ABI conventions on entry).
*
**********************************************************************************************************
*/
.globl _frxt_tick_timer_init
.type _frxt_tick_timer_init,@function
.align 4
_frxt_tick_timer_init:
ENTRY(16)
/* Set up the periodic tick timer (assume enough time to complete init). */
#ifdef XT_CLOCK_FREQ
movi a3, XT_TICK_DIVISOR
#else
movi a2, _xt_tick_divisor
l32i a3, a2, 0
#endif
rsr a2, CCOUNT /* current cycle count */
add a2, a2, a3 /* time of first timer interrupt */
wsr a2, XT_CCOMPARE /* set the comparator */
/*
Enable the timer interrupt at the device level. Don't write directly
to the INTENABLE register because it may be virtualized.
*/
#ifdef __XTENSA_CALL0_ABI__
movi a2, XT_TIMER_INTEN
call0 xt_ints_on
#else
movi a6, XT_TIMER_INTEN
call4 xt_ints_on
#endif
RET(16)
/*
**********************************************************************************************************
* DISPATCH THE HIGH READY TASK
* void _frxt_dispatch(void)
*
* Switch context to the highest priority ready task, restore its state and dispatch control to it.
*
* This is a common dispatcher that acts as a shared exit path for all the context switch functions
* including vPortYield() and vPortYieldFromInt(), all of which tail-call this dispatcher
* (for windowed ABI vPortYieldFromInt() calls it indirectly via _frxt_int_exit() ).
*
* The Xtensa port uses different stack frames for solicited and unsolicited task suspension (see
* comments on stack frames in xtensa_context.h). This function restores the state accordingly.
* If restoring a task that solicited entry, restores the minimal state and leaves CPENABLE clear.
* If restoring a task that was preempted, restores all state including the task's CPENABLE.
*
* Entry:
* pxCurrentTCB points to the TCB of the task to suspend,
* Because it is tail-called without a true function entrypoint, it needs no 'entry' instruction.
*
* Exit:
* If incoming task called vPortYield() (solicited), this function returns as if from vPortYield().
* If incoming task was preempted by an interrupt, this function jumps to exit dispatcher.
*
**********************************************************************************************************
*/
.globl _frxt_dispatch
.type _frxt_dispatch,@function
.align 4
_frxt_dispatch:
#ifdef __XTENSA_CALL0_ABI__
call0 vTaskSwitchContext // Get next TCB to resume
movi a2, pxCurrentTCB
#else
movi a2, pxCurrentTCB
call4 vTaskSwitchContext // Get next TCB to resume
#endif
l32i a3, a2, 0
l32i sp, a3, TOPOFSTACK_OFFS /* SP = next_TCB->pxTopOfStack; */
s32i a3, a2, 0
/* Determine the type of stack frame. */
l32i a2, sp, XT_STK_EXIT /* exit dispatcher or solicited flag */
bnez a2, .L_frxt_dispatch_stk
.L_frxt_dispatch_sol:
/* Solicited stack frame. Restore minimal context and return from vPortYield(). */
l32i a3, sp, XT_SOL_PS
#ifdef __XTENSA_CALL0_ABI__
l32i a12, sp, XT_SOL_A12
l32i a13, sp, XT_SOL_A13
l32i a14, sp, XT_SOL_A14
l32i a15, sp, XT_SOL_A15
#endif
l32i a0, sp, XT_SOL_PC
#if XCHAL_CP_NUM > 0
/* Ensure wsr.CPENABLE is complete (should be, it was cleared on entry). */
rsync
#endif
/* As soons as PS is restored, interrupts can happen. No need to sync PS. */
wsr a3, PS
#ifdef __XTENSA_CALL0_ABI__
addi sp, sp, XT_SOL_FRMSZ
ret
#else
retw
#endif
.L_frxt_dispatch_stk:
#if XCHAL_CP_NUM > 0
/* Restore CPENABLE from task's co-processor save area. */
movi a3, pxCurrentTCB /* cp_state = */
l32i a3, a3, 0
l32i a2, a3, CP_TOPOFSTACK_OFFS /* StackType_t *pxStack; */
l16ui a3, a2, XT_CPENABLE /* CPENABLE = cp_state->cpenable; */
wsr a3, CPENABLE
#endif
/* Interrupt stack frame. Restore full context and return to exit dispatcher. */
call0 _xt_context_restore
/* In Call0 ABI, restore callee-saved regs (A12, A13 already restored). */
#ifdef __XTENSA_CALL0_ABI__
l32i a14, sp, XT_STK_A14
l32i a15, sp, XT_STK_A15
#endif
#if XCHAL_CP_NUM > 0
/* Ensure wsr.CPENABLE has completed. */
rsync
#endif
/*
Must return via the exit dispatcher corresponding to the entrypoint from which
this was called. Interruptee's A0, A1, PS, PC are restored and the interrupt
stack frame is deallocated in the exit dispatcher.
*/
l32i a0, sp, XT_STK_EXIT
ret
/*
**********************************************************************************************************
* PERFORM A SOLICTED CONTEXT SWITCH (from a task)
* void vPortYield(void)
*
* This function saves the minimal state needed for a solicited task suspension, clears CPENABLE,
* then tail-calls the dispatcher _frxt_dispatch() to perform the actual context switch
*
* At Entry:
* pxCurrentTCB points to the TCB of the task to suspend
* Callable from C (obeys ABI conventions on entry).
*
* Does not return to caller.
*
**********************************************************************************************************
*/
.globl vPortYield
.type vPortYield,@function
.align 4
vPortYield:
#ifdef __XTENSA_CALL0_ABI__
addi sp, sp, -XT_SOL_FRMSZ
#else
entry sp, XT_SOL_FRMSZ
#endif
rsr a2, PS
s32i a0, sp, XT_SOL_PC
s32i a2, sp, XT_SOL_PS
#ifdef __XTENSA_CALL0_ABI__
s32i a12, sp, XT_SOL_A12 /* save callee-saved registers */
s32i a13, sp, XT_SOL_A13
s32i a14, sp, XT_SOL_A14
s32i a15, sp, XT_SOL_A15
#else
/* Spill register windows. Calling xthal_window_spill() causes extra */
/* spills and reloads, so we will set things up to call the _nw version */
/* instead to save cycles. */
movi a6, ~(PS_WOE_MASK|PS_INTLEVEL_MASK) /* spills a4-a7 if needed */
and a2, a2, a6 /* clear WOE, INTLEVEL */
addi a2, a2, XCHAL_EXCM_LEVEL /* set INTLEVEL */
wsr a2, PS
rsync
call0 xthal_window_spill_nw
l32i a2, sp, XT_SOL_PS /* restore PS */
wsr a2, PS
#endif
rsil a2, XCHAL_EXCM_LEVEL /* disable low/med interrupts */
#if XCHAL_CP_NUM > 0
/* Save coprocessor callee-saved state (if any). At this point CPENABLE */
/* should still reflect which CPs were in use (enabled). */
call0 _xt_coproc_savecs
#endif
movi a2, pxCurrentTCB
movi a3, 0
l32i a2, a2, 0 /* a2 = pxCurrentTCB */
s32i a3, sp, XT_SOL_EXIT /* 0 to flag as solicited frame */
s32i sp, a2, TOPOFSTACK_OFFS /* pxCurrentTCB->pxTopOfStack = SP */
#if XCHAL_CP_NUM > 0
/* Clear CPENABLE, also in task's co-processor state save area. */
l32i a2, a2, CP_TOPOFSTACK_OFFS /* a2 = pxCurrentTCB->cp_state */
movi a3, 0
wsr a3, CPENABLE
beqz a2, 1f
s16i a3, a2, XT_CPENABLE /* clear saved cpenable */
1:
#endif
/* Tail-call dispatcher. */
call0 _frxt_dispatch
/* Never reaches here. */
/*
**********************************************************************************************************
* PERFORM AN UNSOLICITED CONTEXT SWITCH (from an interrupt)
* void vPortYieldFromInt(void)
*
* This calls the context switch hook (removed), saves and clears CPENABLE, then tail-calls the dispatcher
* _frxt_dispatch() to perform the actual context switch.
*
* At Entry:
* Interrupted task context has been saved in an interrupt stack frame at pxCurrentTCB->pxTopOfStack.
* pxCurrentTCB points to the TCB of the task to suspend,
* Callable from C (obeys ABI conventions on entry).
*
* At Exit:
* Windowed ABI defers the actual context switch until the stack is unwound to interrupt entry.
* Call0 ABI tail-calls the dispatcher directly (no need to unwind) so does not return to caller.
*
**********************************************************************************************************
*/
.globl vPortYieldFromInt
.type vPortYieldFromInt,@function
.align 4
vPortYieldFromInt:
ENTRY(16)
#if XCHAL_CP_NUM > 0
/* Save CPENABLE in task's co-processor save area, and clear CPENABLE. */
movi a3, pxCurrentTCB /* cp_state = */
l32i a3, a3, 0
l32i a2, a3, CP_TOPOFSTACK_OFFS
rsr a3, CPENABLE
s16i a3, a2, XT_CPENABLE /* cp_state->cpenable = CPENABLE; */
movi a3, 0
wsr a3, CPENABLE /* disable all co-processors */
#endif
#ifdef __XTENSA_CALL0_ABI__
/* Tail-call dispatcher. */
call0 _frxt_dispatch
/* Never reaches here. */
#else
RET(16)
#endif
/*
**********************************************************************************************************
* _frxt_task_coproc_state
* void _frxt_task_coproc_state(void)
*
* Implements the Xtensa RTOS porting layer's XT_RTOS_CP_STATE function for FreeRTOS.
*
* May only be called when a task is running, not within an interrupt handler (returns 0 in that case).
* May only be called from assembly code by the 'call0' instruction. Does NOT obey ABI conventions.
* Returns in A15 a pointer to the base of the co-processor state save area for the current task.
* See the detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
*
**********************************************************************************************************
*/
#if XCHAL_CP_NUM > 0
.globl _frxt_task_coproc_state
.type _frxt_task_coproc_state,@function
.align 4
_frxt_task_coproc_state:
movi a15, port_xSchedulerRunning /* if (port_xSchedulerRunning */
l32i a15, a15, 0
beqz a15, 1f
movi a15, port_interruptNesting /* && port_interruptNesting == 0 */
l32i a15, a15, 0
bnez a15, 1f
movi a15, pxCurrentTCB
l32i a15, a15, 0 /* && pxCurrentTCB != 0) { */
beqz a15, 2f
l32i a15, a15, CP_TOPOFSTACK_OFFS
ret
1: movi a15, 0
2: ret
#endif /* XCHAL_CP_NUM > 0 */

@ -0,0 +1,46 @@
/*******************************************************************************
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
*/
/*
* This utility helps benchmarking interrupt latency and context switches.
* In order to enable it, set configBENCHMARK to 1 in FreeRTOSConfig.h.
* You will also need to download the FreeRTOS_trace patch that contains
* portbenchmark.c and the complete version of portbenchmark.h
*/
#ifndef PORTBENCHMARK_H
#define PORTBENCHMARK_H
#if configBENCHMARK
#error "You need to download the FreeRTOS_trace patch that overwrites this file"
#endif
#define portbenchmarkINTERRUPT_DISABLE()
#define portbenchmarkINTERRUPT_RESTORE(newstate)
#define portbenchmarkIntLatency()
#define portbenchmarkIntWait()
#define portbenchmarkReset()
#define portbenchmarkPrint()
#endif /* PORTBENCHMARK */

@ -0,0 +1,225 @@
/*******************************************************************************
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
*/
#include "FreeRTOS.h"
#if XT_USE_THREAD_SAFE_CLIB
#if XSHAL_CLIB == XTHAL_CLIB_XCLIB
#include <errno.h>
#include <sys/reent.h>
#include "semphr.h"
typedef SemaphoreHandle_t _Rmtx;
//-----------------------------------------------------------------------------
// Override this and set to nonzero to enable locking.
//-----------------------------------------------------------------------------
int32_t _xclib_use_mt = 1;
//-----------------------------------------------------------------------------
// Init lock.
//-----------------------------------------------------------------------------
void
_Mtxinit(_Rmtx * mtx)
{
*mtx = xSemaphoreCreateRecursiveMutex();
}
//-----------------------------------------------------------------------------
// Destroy lock.
//-----------------------------------------------------------------------------
void
_Mtxdst(_Rmtx * mtx)
{
if ((mtx != NULL) && (*mtx != NULL)) {
vSemaphoreDelete(*mtx);
}
}
//-----------------------------------------------------------------------------
// Lock.
//-----------------------------------------------------------------------------
void
_Mtxlock(_Rmtx * mtx)
{
if ((mtx != NULL) && (*mtx != NULL)) {
xSemaphoreTakeRecursive(*mtx, portMAX_DELAY);
}
}
//-----------------------------------------------------------------------------
// Unlock.
//-----------------------------------------------------------------------------
void
_Mtxunlock(_Rmtx * mtx)
{
if ((mtx != NULL) && (*mtx != NULL)) {
xSemaphoreGiveRecursive(*mtx);
}
}
//-----------------------------------------------------------------------------
// Called by malloc() to allocate blocks of memory from the heap.
//-----------------------------------------------------------------------------
void *
_sbrk_r (struct _reent * reent, int32_t incr)
{
extern char _end;
extern char _heap_sentry;
static char * _heap_sentry_ptr = &_heap_sentry;
static char * heap_ptr;
char * base;
if (!heap_ptr)
heap_ptr = (char *) &_end;
base = heap_ptr;
if (heap_ptr + incr >= _heap_sentry_ptr) {
reent->_errno = ENOMEM;
return (char *) -1;
}
heap_ptr += incr;
return base;
}
//-----------------------------------------------------------------------------
// Global initialization for C library.
//-----------------------------------------------------------------------------
void
vPortClibInit(void)
{
}
//-----------------------------------------------------------------------------
// Per-thread cleanup stub provided for linking, does nothing.
//-----------------------------------------------------------------------------
void
_reclaim_reent(void * ptr)
{
}
#endif /* XSHAL_CLIB == XTHAL_CLIB_XCLIB */
#if XSHAL_CLIB == XTHAL_CLIB_NEWLIB
#include <errno.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "semphr.h"
static SemaphoreHandle_t xClibMutex;
static uint32_t ulClibInitDone = 0;
//-----------------------------------------------------------------------------
// Get C library lock.
//-----------------------------------------------------------------------------
void
__malloc_lock(struct _reent * ptr)
{
if (!ulClibInitDone)
return;
xSemaphoreTakeRecursive(xClibMutex, portMAX_DELAY);
}
//-----------------------------------------------------------------------------
// Release C library lock.
//-----------------------------------------------------------------------------
void
__malloc_unlock(struct _reent * ptr)
{
if (!ulClibInitDone)
return;
xSemaphoreGiveRecursive(xClibMutex);
}
//-----------------------------------------------------------------------------
// Lock for environment. Since we have only one global lock we can just call
// the malloc() lock function.
//-----------------------------------------------------------------------------
void
__env_lock(struct _reent * ptr)
{
__malloc_lock(ptr);
}
//-----------------------------------------------------------------------------
// Unlock environment.
//-----------------------------------------------------------------------------
void
__env_unlock(struct _reent * ptr)
{
__malloc_unlock(ptr);
}
//-----------------------------------------------------------------------------
// Called by malloc() to allocate blocks of memory from the heap.
//-----------------------------------------------------------------------------
void *
_sbrk_r (struct _reent * reent, int32_t incr)
{
extern char _end;
extern char _heap_sentry;
static char * _heap_sentry_ptr = &_heap_sentry;
static char * heap_ptr;
char * base;
if (!heap_ptr)
heap_ptr = (char *) &_end;
base = heap_ptr;
if (heap_ptr + incr >= _heap_sentry_ptr) {
reent->_errno = ENOMEM;
return (char *) -1;
}
heap_ptr += incr;
return base;
}
//-----------------------------------------------------------------------------
// Global initialization for C library.
//-----------------------------------------------------------------------------
void
vPortClibInit(void)
{
configASSERT(!ulClibInitDone);
xClibMutex = xSemaphoreCreateRecursiveMutex();
ulClibInitDone = 1;
}
#endif /* XSHAL_CLIB == XTHAL_CLIB_NEWLIB */
#endif /* XT_USE_THREAD_SAFE_CLIB */

@ -0,0 +1,244 @@
/*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that has become a de facto standard. *
* *
* Help yourself get started quickly and support the FreeRTOS *
* project by purchasing a FreeRTOS tutorial book, reference *
* manual, or both from: http://www.FreeRTOS.org/Documentation *
* *
* Thank you! *
* *
***************************************************************************
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 from the following
link: http://www.freertos.org/a00114.html
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong?" *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details.
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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and 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
#ifndef __ASSEMBLER__
#include <stdint.h>
#include <xtensa/tie/xt_core.h>
#include <xtensa/hal.h>
#include <xtensa/config/core.h>
#include <xtensa/config/system.h> /* required for XSHAL_CLIB */
#include <xtensa/xtruntime.h>
//#include "xtensa_context.h"
/*-----------------------------------------------------------
* 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 int8_t
#define portFLOAT float
#define portDOUBLE double
#define portLONG int32_t
#define portSHORT int16_t
#define portSTACK_TYPE uint8_t
#define portBASE_TYPE int
typedef portSTACK_TYPE StackType_t;
typedef portBASE_TYPE BaseType_t;
typedef unsigned portBASE_TYPE UBaseType_t;
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
/*-----------------------------------------------------------*/
// portbenchmark
#include "portbenchmark.h"
/* Critical section management. NW-TODO: replace XTOS_SET_INTLEVEL with more efficient version, if any? */
// These cannot be nested. They should be used with a lot of care and cannot be called from interrupt level.
#define portDISABLE_INTERRUPTS() do { XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); } while (0)
#define portENABLE_INTERRUPTS() do { portbenchmarkINTERRUPT_RESTORE(0); XTOS_SET_INTLEVEL(0); } while (0)
// These can be nested
#define portCRITICAL_NESTING_IN_TCB 1 // For now, let FreeRTOS' (tasks.c) manage critical nesting
void vTaskEnterCritical(void);
void vTaskExitCritical(void);
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
// Cleaner and preferred solution allows nested interrupts disabling and restoring via local registers or stack.
// They can be called from interrupts too.
static inline unsigned portENTER_CRITICAL_NESTED() { unsigned state = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); return state; }
#define portEXIT_CRITICAL_NESTED(state) do { portbenchmarkINTERRUPT_RESTORE(state); XTOS_RESTORE_JUST_INTLEVEL(state); } while (0)
// These FreeRTOS versions are similar to the nested versions above
#define portSET_INTERRUPT_MASK_FROM_ISR() portENTER_CRITICAL_NESTED()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(state) portEXIT_CRITICAL_NESTED(state)
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 4
#define portNOP() XT_NOP()
/*-----------------------------------------------------------*/
/* Fine resolution time */
#define portGET_RUN_TIME_COUNTER_VALUE() xthal_get_ccount()
/* Kernel utilities. */
void vPortYield( void );
void _frxt_setup_switch( void );
#define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) if( ( x ) != 0 ) { _frxt_setup_switch(); }
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
// When coprocessors are defined, we to maintain a pointer to coprocessors area.
// We currently use a hack: redefine field xMPU_SETTINGS in TCB block as a structure that can hold:
// MPU wrappers, coprocessor area pointer, trace code structure, and more if needed.
// The field is normally used for memory protection. FreeRTOS should create another general purpose field.
typedef struct {
#if XCHAL_CP_NUM > 0
volatile StackType_t* coproc_area; // Pointer to coprocessor save area; MUST BE FIRST
#endif
#if portUSING_MPU_WRAPPERS
// Define here mpu_settings, which is port dependent
int mpu_setting; // Just a dummy example here; MPU not ported to Xtensa yet
#endif
#if configUSE_TRACE_FACILITY_2
struct {
// Cf. porttraceStamp()
int taskstamp; /* Stamp from inside task to see where we are */
int taskstampcount; /* A counter usually incremented when we restart the task's loop */
} porttrace;
#endif
} xMPU_SETTINGS;
// Main hack to use MPU_wrappers even when no MPU is defined (warning: mpu_setting should not be accessed; otherwise move this above xMPU_SETTINGS)
#if (XCHAL_CP_NUM > 0 || configUSE_TRACE_FACILITY_2) && !portUSING_MPU_WRAPPERS // If MPU wrappers not used, we still need to allocate coproc area
#undef portUSING_MPU_WRAPPERS
#define portUSING_MPU_WRAPPERS 1 // Enable it to allocate coproc area
#define MPU_WRAPPERS_H // Override mpu_wrapper.h to disable unwanted code
#define PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA
#endif
// porttrace
#if configUSE_TRACE_FACILITY_2
#include "porttrace.h"
#endif
// configASSERT_2 if requested
#if configASSERT_2
#include <stdio.h>
void exit(int);
#define configASSERT( x ) if (!(x)) { porttracePrint(-1); printf("\nAssertion failed in %s:%d\n", __FILE__, __LINE__); exit(-1); }
#endif
/* C library support -- only XCLIB and NEWLIB are supported. */
/* To enable thread-safe C library support, XT_USE_THREAD_SAFE_CLIB must be
defined to be > 0 somewhere above or on the command line. */
#if (XT_USE_THREAD_SAFE_CLIB > 0u) && (XSHAL_CLIB == XTHAL_CLIB_XCLIB)
extern void vPortClibInit(void);
// No cleanup necessary at this time.
#define portCLEAN_UP_TCB(pxTCB)
#endif // XCLIB support
#if (XT_USE_THREAD_SAFE_CLIB > 0u) && (XSHAL_CLIB == XTHAL_CLIB_NEWLIB)
extern void vPortClibInit(void);
// This C library cleanup is not currently done by FreeRTOS when deleting a task
#include <stdio.h>
#define portCLEAN_UP_TCB(pxTCB) vPortCleanUpTcbClib(&((pxTCB)->xNewLib_reent))
static inline void vPortCleanUpTcbClib(struct _reent *ptr)
{
FILE * fp = &(ptr->__sf[0]);
int i;
for (i = 0; i < 3; ++i, ++fp) {
fp->_close = NULL;
}
}
#endif // NEWLIB support
#endif // __ASSEMBLER__
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

@ -0,0 +1,42 @@
/*******************************************************************************
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/*
* This utility helps tracing the entering and exiting from tasks. It maintains a circular buffer
* of tasks in the order they execute, and their execution time.
* In order to enable it, set configUSE_TRACE_FACILITY_2 to 1 in FreeRTOSConfig.h.
* You will also need to download the FreeRTOS_trace patch that contains
* porttrace.c and the complete version of porttrace.h
*/
#ifndef PORTTRACE_H
#define PORTTRACE_H
#if configUSE_TRACE_FACILITY_2
#error "You need to download the FreeRTOS_trace patch that overwrites this file"
#endif
#define porttracePrint(nelements)
#define porttraceStamp(stamp, count_incr)
#endif /* PORTTRACE_H */

@ -0,0 +1,764 @@
FreeRTOS Port for Xtensa Configurable and Diamond Processors
============================================================
FreeRTOS Kernel Version 10.0.0
Introduction
------------
This document describes the Xtensa port for FreeRTOS multitasking RTOS.
For an introduction to FreeRTOS itself, please refer to FreeRTOS
documentation.
This port currently works with FreeRTOS kernel version 10.0.0.
Xtensa Configuration Requirements and Restrictions
--------------------------------------------------
The Xtensa configurable architecture supports a vast space of processor
features. This port supports all of them, including custom processor
extensions defined in the TIE language, with certain minimum
requirements. You must use Xtensa Tools to compile and link FreeRTOS and
your application for your Xtensa configuration. The port uses the Xtensa
Hardware Abstraction Layer (HAL) to adapt to your Xtensa configuration.
NOTE: It may be possible to build and run this with the open-source
xtensa-linux tools provided you have the correct overlay for your Xtensa
configuration. However, this has not been tested and is currently not
supported by Cadence.
This port includes optional reentrancy support for the 'newlib' and
'xclib' C runtime libraries distributed with Xtensa Tools, providing
thread-safety on a per task basis (for use in tasks only, not interrupt
handlers).
NOTE: At this time only 'newlib' and 'xclib' C libraries are supported
for thread safety. The 'uclibc' library is not reentrant and does not
provide thread safety at this time. However, if you are not concerned
with reentrancy then you can use any of these libraries.
This port also includes a simple example application that may run on
a supported board or the Xtensa instruction set simulator (ISS). There
are also a couple of test programs used in maintaining the port, which
serve as additional examples.
FreeRTOS for Xtensa configurable processors requires the following minimum
processor configuration options:
- Timer interrupt option with at least one interruptible timer.
- Interrupt option (implied by the timer interrupt option).
- Exception Architecture 2 (XEA2). Please note that XEA1 is NOT supported.
All 'Diamond', 'Xtensa 6', 'Xtensa LX' and 'Xtensa LX2' processors and
most 'Xtensa T1050' processors are configured with XEA2.
All Diamond processor cores meet these requirements and are supported.
Minimal support for certain evaluation boards is provided via a board
independent XTBSP API implemented by a board specific library distributed
with the Xtensa Tools. This provides the board clock frequency and basic
polled drivers for the display and console device. Note that XTBSP
is not a tradtional RTOS "board support package" with RTOS specific
interrupt-driven drivers - it is not specific to any RTOS. Note that
FreeRTOS can run on any Xtensa or Diamond board without this board support
(a "raw" platform), but you will have to provide the clock frequency
and drivers for any on-board devices you want to use.
Installation
------------
The Xtensa port of FreeRTOS is available at this location:
https://github.com/foss-xtensa/amazon-freertos
This download includes the core FreeRTOS source and include files needed
to build the port. You can also download the official release of FreeRTOS
version 1.0.0 or later from this location:
https://github.com/aws/amazon-freertos
The Xtensa port files are currently not included in the official package.
All source is provided along with a Makefile that works for any host
platform supported by Xtensa Tools (Windows, Linux). These instructions
are written for Windows users, but can easily be understood and adapted
to other host platforms.
First install the FreeRTOS common package in a directory of your choosing.
The structure of that package will look like this:
<install directory>
|-- demos
| `-- cadence
| `-- sim
| |-- common
| | |-- application_code
| | | `-- cadence_code
| | `-- config_files
| `-- xplorer
`-- lib
|-- FreeRTOS
| `-- portable
| |-- Common
| |-- MemMang
| `-- XCC
| `-- Xtensa
`-- include
`-- private
The Xtensa Tools are available from Cadence as part of a processor
license. Be sure you have installed the Xtensa Tools and your processor
configuration.
Building FreeRTOS for Xtensa
----------------------------
To build the FreeRTOS library and the example programs, go into the
directory 'demos/cadence/sim' and use the makefile in that directory.
"make all" will build all the examples. There is another makefile in
the 'lib/FreeRTOS/portable/XCC/Xtensa' directory that builds just the
FreeRTOS library.
By default, you will build for the Xtensa instruction set simulator. If
you have a supported emulation board, you can build to run on that. You
can also build to run on a raw Xtensa core with no board support, a
good starting point for supporting your own target platform. Cadence
recommends doing functional development on the simulator because it
is easier to debug with, then move to a board if/when you need to test
hardware drivers or real-time performance.
The provided makefile simplifies building FreeRTOS and the example
for your Xtensa configuration and platform (ISS, board, etc.). There
are detailed instructions in the comments at the top of the makefile.
The makefiles work on Windows and Linux and support incremental builds.
The build for each Xtensa configuration and target platform is placed in
a subdirectory so several core and platform builds can co-exist even with
incremental rebuilds. You may specify the root of the build area (if tou
want it to be elsewhere than under the source tree) by defining BLDROOT
either in the make command or your shell environment.
Building the FreeRTOS Library
-----------------------------
First, be sure you have installed Xtensa Tools and your processor
configuration, and be sure that Xtensa Tools are in your search path.
You can use xt-make, which comes with the Xtensa Tools, to run the
makefiles.
Change directories to the Xtensa port directory:
> cd lib/FreeRTOS/portable/XCC/Xtensa
Now build the FreeRTOS RTOS as a library (libfreertos.a) as follows:
> xt-make
which by default builds for the simulator (TARGET=sim), or:
> xt-make TARGET=board
which builds for a supported board. Note that the board type does not
need to be specified when building the FreeRTOS library.
If you are building for an Xtensa processor configuration that is not the
default you selected when you installed Xtensa Tools, you need to define the
environment variable XTENSA_CORE. If your configuration is not in the
default registry you selected when you installed Xtensa Tools, you also
need to define the environment variable XTENSA_SYSTEM. See tools manuals.
You can avoid defining these in your environment if you pass the variables
you need to redefine into xt-make as follows:
> xt-make XTENSA_CORE=<your_config_name> XTENSA_SYSTEM=<your_registry> ...
There are more details about build options in the comment in the Makefile.
After the library has been built, you must link your application with this
library in order to use FreeRTOS.
Building the FreeRTOS Examples
------------------------------
The provided examples are designed to run on the Xtensa instruction set
simulator (ISS) or a supported evaluation board programmed with your
Xtensa processor configuration.
To build the examples for the default platform (simulator):
> cd demos/cadence/sim
> xt-make all
which is the same as
> xt-make all TARGET=sim
The boards currently supported are the Xilinx ML605 and KC705 FPGA
development boards. To target these boards, type
> xt-make all TARGET=ml605
or
> xt-make all TARGET=kc705
To build in a location other than the default, specify the new location
using the BLDROOT variable. Note that this makefile will invoke the
FreeRTOS library build makefile automatically, passing on the relevant
parameters based on what you specified.
You can override the default compilation options by specifying the new
options via CFLAGS. For example:
> xt-make all TARGET=sim CFLAGS="-O2 -Os -g"
This compiles the examples and links them with the FreeRTOS library
libfreertos.a and the appropriate linker-support package (LSP) for your
target platform (you can override the LSP by adding LSP=<lsp> to the
xt-make command line). The resulting ELF files can be downloaded and
executed on the target. The example binaries appear in the platform
specific subdirectory described earlier.
To build your application with thread-safe C library support, you
need to make certain modifications to the application to plug in and
invoke the reentrancy support. This allows each task to use the library
without interference with other tasks (it is not safe for interrupt
handlers to call the C library).
First, you must define
XT_USE_THREAD_SAFE_CLIB
to a nonzero value either in xtensa_config.h or on the compiler's command
line. Note that the default xtensa_config.h provided with this port does
define this to 1 if either newlib or xclib is detected.
Then, you must also make sure to allocate extra space on the stack for
each task that will use the C library reentrant functions. This extra
space is to be allocated over and above the actual stack space required
by the task itself. The define
XT_STACK_EXTRA_CLIB
specifies the amount of extra space to be added on to the stack to allow
saving the context for the C library as well as the coprocessors if any.
E.g. if your task requires 2000 bytes of stack space, you must allocate
(2000 + XT_STACK_EXTRA_CLIB) bytes for the stack.
IMPORTANT NOTE
--------------
The header file FreeRTOS.h, which is a part of the core FreeRTOS sources,
includes <reent.h> if thread safety for the C libraries is enabled. For
xclib, this file exists in <sys/reent.h> and so is reported as missing.
To work around this, the makefiles supplied with this port will copy the
reent.h header into the build directory during the build process. If you
use a different build process, then you must make sure to copy this file
to a location that is included in the list of include paths. This can be
the build directory or the directory that contains the Xtensa port source
files.
Running or Debugging an Application
-----------------------------------
To execute the example application on the simulator:
> xt-run [--turbo] example.exe
The option --turbo provides much faster, but non-cycle-accurate simulation
(the --turbo option is only available with Xtensa Tools version 7 or later).
To execute on the simulator using the Xplorer GUI based debugger:
> xplorer --debug example.exe
To execute on a supported evaluation board, download example.exe per
instructions in the tools manuals. Be sure the board has been programmed
with the correct configuration and is set up to boot from RAM and debug
a downloaded program! Optionally you may connect a terminal or terminal
emulator to the serial port on the board with settings as described in
the board user manual, and see the output of printf on the terminal.
To obtain I/O on a "raw" platform such as an unsupported board, you need
to provide low level I/O drivers (eg. inbyte() and outbyte() for character
I/O if you want to use printf etc.). You can run "raw" executables on
any Xtensa platform, including simulator and any board, but you will not
see any behavior specific to the platform (eg. display, printed output,
stopping simulation at end of program). You can, while debugging, use a
debugger mechanism called GDBIO to obtain basic I/O. To use GDBIO, link
with the gdbio LSP. Refer to Xtensa tools documentation for details.
Task Stack Sizes
----------------
The application must ensure that every task has enough space for its
stack. Each task needs enough space for its own use, its own interrupt
stack frame (defined in xtensa_context.h) and space to save coprocessor
state, if any. Several factors influence the size of the stack required,
including the compiler optimization level and the use of the C library.
Calls to standard output functions such as printf() can use up a lot of
stack space. The tool xt-stack-usage is helpful in determining safe stack
sizes for your application.
Some macros are provided in xtensa_config.h to help determine the stack
size for tasks that do and do not use the C library. Use these as the
basis for each task's stack size. They are minimum requirements taking
into account your configuration and use of the C library. In particular,
the define
XT_STACK_MIN_SIZE
defines the minimum stack size for any task. Be very careful if you try
to use a stack size smaller than this minimum. Stack overruns can cause
all kinds of hard-to-debug errors. It is recommended that you enable the
FreeRTOS stack checking features during development.
WARNING: The newlib printf() function uses a lot of stack space. Be very
careful in using it. Optionally you can use the 'libxtutil' library for
output - it implements a subset of printf() that has smaller code size
and uses far less stack space. More information about this library is in
the Xtensa Tools documentation.
Interrupt Stack
---------------
Beginning with port version 1.2, the port uses a separate interrupt stack
for handling interrupts. Thus, it is no longer necessary for each task to
reserve space on its stack to handle interrupts. The size of the interrupt
stack is controlled by the parameter "configISR_STACK_SIZE" defined in
FreeRTOSConfig.h. Define this carefully to match your system requirements.
Assembler / Compiler Switches
-----------------------------
The following are compiler switches are used by the provided
Makefile in building the FreeRTOS library and example application.
These can be modified by editing the Makefile or by overriding the
CFLAGS variable in the make command line, for example:
> xt-make CFLAGS="-O2 -DXT_USE_THREAD_SAFE_CLIB"
-g Specifies debug information.
-c Specifies object code generation.
-On Sets compiler optimization level n (default -O0).
-mlongcalls Allows assembler and linker to convert call
instructions to longer indirect call sequences
when target is out of range.
-x assembler-with-cpp Passes .s and .S files through C preprocessor.
-Dmacro Define a preprocessor macro with no value.
-Dmacro=value Define a preprocessor macro with a value.
See the compiler / linker documentation for a full list of switches and
their use.
Many definitions can be provided at compile-time via the -D option
without editing the source code. Here are some of the more useful ones:
XT_USE_THREAD_SAFE_CLIB Enable support for the reentrancy to provide
thread-safety for the newlib and xclib libraries
supplied with Xtensa Tools. Default ON.
Note, the follwing defines are unique to the Xtensa port so have names
beginning with "XT_".
XT_SIMULATOR Set this if building to run on the simulator.
Takes advantage of certain simulator control
and reporting facilities, and adjusts timing
of periodic tick to provide a more acceptable
performance in simulation (see XT_CLOCK_FREQ).
Set by default unless PLATFORM is overridden.
XT_BOARD Set this if building for a supported board.
Be sure to specify the correct LSP for the
board. See the example makefile for usage.
XT_CLOCK_FREQ=freq Specifies the target processor's clock
frequency in Hz. Used primarily to set the
timer that generates the periodic interrupt.
Defaults are provided and may be edited in
xtensa_timer.h (see comments there also).
Default for simulator provides more acceptable
performance, but cannot provide real-time
performance due to variation in simulation
speed per host platform and insufficient
cycles between interrupts to process them.
Supported board platforms by default leave
this undefined and compute the clock frequency
at initialization unless this is explicitly
defined.
XT_TICK_PER_SEC=n Specifies the frequency of the periodic tick.
XT_TIMER_INDEX=n Specifies which timer to use for periodic tick.
Set this if your Xtensa processor configuration
provides more than one suitable timer and you
want to override the default. See xtensa_timer.h .
XT_INTEXC_HOOKS Enables hooks in interrupt vector handlers
to support dynamic installation of exception
and interrupt handlers. Disabled by default.
XT_USE_OVLY Enable code overlay support. It uses a mutex,
hence configUSE_MUTEX must be enabled. This
option is currently unsupported.
XT_USE_SWPRI Enable software prioritization of interrupts.
Enabling this will prioritize interrupts with
higher bit numbers over those with lower bit
numbers at the same level. This works only for
low and medium priority interrupts that can be
dispatched to C handlers.
Register Usage and Stack Frames
-------------------------------
The Xtensa architecture specifies two ABIs that determine how the general
purpose registers a0-a15 are used: the standard windowed ABI use with
the Xtensa windowed register file architecture, and the optional and
more conventional Call0 ABI (required for Xtensa configurations without
a windowed register file).
Xtensa processors may have other special registers (including co-processor
registers and other TIE "states") that are independent of this choice
of ABI. See Xtensa documentation for more details.
In the windowed ABI the registers of the current window are used as follows:
a0 = return address
a1 = stack pointer (alias sp)
a2 = first argument and result of call (in simple cases)
a3-7 = second through sixth arguments of call (in simple cases).
Note that complex or large arguments are passed on the
stack. Details are in the Xtensa Tools manuals.
a8-a15 = available for use as temporaries.
There are no callee-save registers. The windowed hardware automatically
saves registers a0-a3 on a call4, a0-a8 on a call8, a0-a12 on a call12,
by rotating the register window. Hardware triggers window overflow and
underflow exceptions as necessary when registers outside the current
window need to be spilled to preallocated space in the stack frame, or
restored. Complete details are in the Xtensa manuals. The entire windowed
register file is saved and restored on interrupt or task context switch.
The Call0 ABI does not make use of register windows, relying instead
on a fixed set of 16 registers without window rotation.
The Call0 ABI is more conventional and uses registers as follows:
a0 = return address
a1 = stack pointer (alias sp)
a2 = first argument and result of call (in simple cases)
a3-7 = second through sixth arguments of call (in simple cases).
Note that complex or large arguments are passed on the
stack. Details are in the Xtensa Tools manuals.
a8-a11 = scratch.
a12-a15 = callee-save (a function must preserve these for its caller).
On a FreeRTOS API call, callee-save registers are saved only when a task
context switch occurs, and other registers are not saved at all (the caller
does not expect them to be preserved). On an interrupt, callee-saved
registers might only be saved and restored when a task context-switch
occurs, but all other registers are always saved and restored.
An Xtensa processor has other special registers independent of the ABI,
depending on the configuration (including co-processor registers and other
TIE state) that are part of the task context. FreeRTOS preserves all such
registers over an unsolicited context-switch triggered by an interrupt.
However it does NOT preserve these over a solicited context-switch during
a FreeRTOS API call. This bears some explanation. These special registers
are either ignored by the compiler or treated as caller-saved, meaning
that if kept "live" over a function call (ie. need to be preserved)
they must be saved and restored by the caller. Since solicited entry to
FreeRTOS is always made by a function call, FreeRTOS assumes the caller
has saved any of these registers that are "live". FreeRTOS avoids a lot
of overhead by not having to save and restore every special register
(there can be many) on every solicited context switch.
As a consequence, the application developer should NOT assume that special
registers are preserved over a FreeRTOS API call such as vTaskDelay().
If multiple tasks use a register, the caller must save and restore it.
The saved context stack frames for context switches that occur as
a result of interrupt handling (interrupt frame) or from task-level
API calls (solicited frame) are described in human readable form in
xtensa_context.h . All suspended tasks have one of these two types
of stack frames. The top of the suspended task's stack is pointed to
by pxCurrentTCB->pxTopOfStack. A special location common to both stack
frames differentiates solicited and interrupt stack frames.
Improving Performance, Footprint, or Ease of Debugging
------------------------------------------------------
By default FreeRTOS for Xtensa is built with debug (-g) and without
compiler optimizations (-O0). This makes debugging easier. Of course,
-O0 costs performance and usually also increases stack usage. To make
FreeRTOS run faster you can change the Makefile to enable the desired
optimizations or set a predefined optimization level (-O<level>) .
Maximum performance is achieved with -O3 -ipa, but that might increase
the footprint substantially. A good compromise is -O2. See the compiler
manual for details.
Minimal footprint is achieved by optimizing for space with -Os, at the
cost of some performance. See the compiler manual for details.
The Xtensa architecture port-specific assembly files are coded with no
file-scope labels inside functions (all labels inside functions begin with
".L"). This allows a profiler to accurately associate an address with a
function, and also allows the debugger's stack trace to show the correct
function wherever the program counter is within that function. However
there are some tradeoffs in debugging. Local (".L") labels are not
visible to the debugger, so the following limitations may be observed
during debugging:
- You cannot set a breakpoint on a local label inside a function.
- Disassembly will show the entire function, but will get out of sync and
show incorrect opcodes if it crosses any padding before an aligned local
branch target (".L" label, not ".Ln"). Restart disassembly specifying an
address range explicitly between points where there is padding.
Since FreeRTOS is provided in source form, it is not difficult to remove
the ".L" and ".Ln" prefixes from local labels if you want them visible.
They can also be made visible by passing the '-L' option to the assembler
and linker (see the assembler and linker manuals for details).
Interrupt and Exception Handling
--------------------------------
FreeRTOS provides a complete set of efficient exception and first-level
interrupt handlers installed at the appropriate exception and interrupt
vector locations. The Xtensa architecture supports several different
classes of exceptions and interrupts. Being a configurable architecture,
many of these are optional, and the vector locations are determined by
your processor configuration. (Note that Diamond cores are pre-configured
with specific vector locations.) The handlers provided use conditional
compilation to adapt to your processor configuration and include only
the code that is needed.
Xtensa vector locations may reside almost anywhere, including in ROM.
The amount of code space available at each of these locations is
often very small (e.g. due to following vectors). A small stub of
code installed at the vector jumps to the corresponding handler,
usually in RAM. The exception and interrupt handlers are defined in
xtensa_vectors.S. They are not specific to FreeRTOS, but call into
FreeRTOS where appropriate via macros defined in xtensa_rtos.h .
The handlers provided for low and medium priority interrupts are just
dispatchers that save relevant state and call user-definable handlers.
See the files xtensa_vectors.S and xtensa_api.h for more details of how
to create and install application-specific user interrupt handlers.
Similarly, user-defined handlers can be installed for exceptions (other
than a few which are always handled by the OS).
The high priority interrupt handlers provided may be considered templates
into which the application adds code to service specific interrupts.
The places where application handlers should be inserted are tagged with
the comment "USER_EDIT" in xtensa_vectors.S.
This FreeRTOS port supports strict priority-based nesting of interrupts.
An interrupt may only nest on top of one of strictly lower priority.
Equal priority interrupts concurrently pending are handled in an
application-defined sequence before any lower priority interrupts
are handled. During interrupt and exception handling, the processor's
interrupt level (PS.INTLEVEL) is used to control the interrupt priority
level that can be accepted; interrupt sources are not controlled
individually by FreeRTOS (the application is free to access the INTENABLE
register directly to enable/disable individual interrupts, eg. using
Xtensa HAL services). This approach provides the most deterministic
bounds on interrupt latency (for a given priority) and stack depth.
Software prioritization of interrupts at the same priority is controlled
by the definition of XT_USE_SWPRI. See above for a description of this
parameter.
The following subsections describe the handling of each class of exception
and interrupt in more detail. Many have nothing to do with FreeRTOS but
are mentioned because there is code to handle them in xtensa_vectors.S.
User Exception and Interrupt Handler (Low/Medium Priority):
All Xtensa 'general exceptions' come to the user, kernel, or double
exception vector. The exception type is identified by the EXCCAUSE
special register (level 1 interrupts are one particular cause of a
general exception). This port sets up PS to direct all such exceptions
to the user vector. Exceptions taken at the other two vectors usually
indicate a kernel or application bug.
Level 1 interrupts are identified at the beginning of the handler
and are dispatched to a dedicated handler. Then, syscall and alloca
exceptions are identified and dispatched to special handlers described
below. After this, coprocessor exceptions are identified and dispatched
to the coprocessor handler.
Any remaining exceptions are processed as follows:
Having allocated the exception stack frame, the user exception handler
saves the current task state and sets up a C environment and enables
the high-priority class of interrupts (which do not interact with
FreeRTOS), then reads EXCCAUSE and uses the cause (number) to index
into a table of user-specified handlers. The correct handler is then
called. If the handler returns, the context is restored and control is
returned to the code that caused the exception. The user-defined handler
may alter the saved context, or any other system state, that allows the
faulting instruction to be retried.
If the cause is a level 1 (low-priority) or medium-priority interrupt,
the handler enables all interrupts above that priority level after
saving the task context. It then sets up the environment for C code
and then calls the handler (found in the handler table) for the
interrupt number. If the user has not specified a handler, then the
default handler will be called, which will terminate the program.
If the interrupt is for the system timer, it calls a special interrupt
handler for the system timer tick, which calls _frxt_timer_int then
clears its bit from the mask. This interrupt cannot be hooked by the
user-defined handler.
Finally, the handler calls _frxt_int_exit to allow FreeRTOS to perform
any scheduling necessary and return either to the interrupted task
or another.
If software prioritization is enabled, the handler will re-enable all
interrupts at the same level that are numerically higher than the current
one, before calling the user handler. This allows a higher priority
interrupt to pre-empt the lower priority handler.
Medium Priority Interrupt Handlers:
Medium priority interrupts are those at levels 2 up to XCHAL_EXCM_LEVEL,
a configuration-specific maximum interrupt level affected by the global
'exception mode' bit in the processor status word (PS.EXCM).
Interrupt levels above XCHAL_EXCM_LEVEL are of the high-priority class.
The Xtensa hardware documentation considers medium priority interrupts
to be a special case of high-priority interrupts, but from a software
perspective they are very different.
Dispatch of medium-priority interrupts is discussed in the section
above.
High Priority Interrupt Handlers:
High priority interrupts are those strictly above XCHAL_EXCM_LEVEL,
a configuration-specific maximum interrupt level affected by the
global 'exception mode' bit in the processor status word (PS.EXCM).
High priority handlers may not directly interact with FreeRTOS at all,
and are described here only for the sake of completeness. They must
be coded in assembler (may not be coded in C) and are intended to be
used for handling extremely high frequency hardware events that need
to be handled in only a few cycles. A high priority interrupt handler
may trigger a software interrupt at a medium or low priority level to
occasionally signal FreeRTOS. Please see Xtensa documentation.
There is a separate vector and a few special registers for each high
priority interrupt, providing for fast dispatch and efficient nesting
on top of lower priority interrupts. Handlers are templates included
only for the vectors that exist in your Xtensa processor configuration.
These templates are written for only one interrupt per high priority
level to minimize latency servicing very fast time-critical interrupts.
The vector code jumps to the corresponding first-level interrupt handler,
which then executes application-provided assembler code before returning
quickly to the interrupted task or lower priority handler.
Kernel Exception Handler:
Kernel mode is not used in this port of FreeRTOS, and therefore kernel
exceptions should not happen. A stub is provided for the vector that
triggers the debugger (if connected) or calls _xt_panic to freeze the
processor should a kernel exception occur.
Alloca Exception Handler:
Alloca exceptions are generated by the 'movsp' instruction, which
is used only in the windowed ABI. Its purpose is to allocate some
space on top of the stack. Because the window hardware may have
spilled some registers to the 16 byte "base save" area below the
stack pointer, it is necessary to protect those values. The alloca
handler accomplishes this quickly without setting up an interrupt
frame or entering FreeRTOS, by emulating a register underflow and
re-executing 'movsp'.
Syscall Exception Handler:
Syscall exceptions are generated by a 'syscall' instruction.
The windowed ABI specifies that executing this instruction with
a value of zero in register a2 must spill any unsaved registers
in the windowed register file to their pre-determined locations
on the caller's stack. The handler does exactly that, and skips
over the 'syscall' instruction before returning to the caller.
If a2 is non-zero, the handler returns a2 == -1 to the caller.
Co-Processor Exception Handler:
A co-processor exception is generated when a task accesses a
co-processor that it does not "own". Ownership represents which
task's state is currently in the co-processor. Co-processors are
context-switched "lazily" (on demand) only when a non-owning task
uses a co-processor instruction, otherwise a task retains ownership
even when it is preempted from the main processor. The co-processor
exception handler performs the context-switch and manages ownership.
Co-processors may not be used by any code outside the context of a
task. A co-processor exception triggered by code that is not part
of a running task is a fatal error and FreeRTOS for Xtensa will panic.
This restriction is intended to reduce the overhead of saving and
restoring co-processor state (which can be quite large) and in
particular remove that overhead from interrupt handlers.
Debug Exception Handler:
A debug exception is caused as a result of running code, such as by
a 'break' instruction or hardware breakpoints and watchpoints, or
as a result of an external debug interrupt, such as from an OCD based
debugger or multiprocessor debug events ("breakin/breakout"). If the
processor is running in OCD mode under control of an OCD-based debugger,
the trigger event immediately halts the processor and gives control to
the OCD debugger. Otherwise control is transferred to the debug vector.
The debug vector handler calls the simulator if running on the ISS,
which then takes control and interacts with any attached debugger.
If running on hardware and not in OCD mode, debug exceptions are not
expected, so the debug handler calls _xt_panic to freeze the processor.
Double Exception Handler:
A double exception is a general exception that happens while the
processor is in exception mode (PS.EXCM set), and thus indicates a
bug in kernel code. The double exception vector handler triggers
the debugger (if connected) or calls _xt_panic to freeze the
processor.
Window Overflow and Underflow Exception Handlers:
Window overflow and underflow handlers are required for use of the
windowed ABI. Each has its own dedicated vector and highly optimized
code that is independent of OS. See Xtensa documentation for details.
Hooks for Dynamic Installation of Handlers:
Optional hooks are provided in the user exception and low level
interrupt handler and all medium and high priority interrupt handlers,
to dynamically install a handler function (which may be coded in C,
unless in a high-priority interrupt handler). These hooks are enabled
and used by automatic regression tests, they are not part of a normal
FreeRTOS build. However an application is free to take advantage of
them. The interrupt/exception hooks are described in xtensa_rtos.h .
It is recommended that the application not make use of these hooks, but
rather use xt_set_interrupt_handler() and xt_set_exception_handler()
to install application-specific handlers. This method is more convenient
and allows arguments to be passed to the handlers. Software prioritization
of interrupts works only with this method. See xtensa_api.h for details.
Overlay Support
Code overlays are currently not supported for FreeRTOS. This will be
supported in a future release. Make sure that the option XT_USE_OVLY is
never defined when building.
-End-

@ -0,0 +1,122 @@
/*******************************************************************************
Copyright (c) 2006-2015 Cadence Design Systems Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/
/******************************************************************************
Xtensa-specific API for RTOS ports.
******************************************************************************/
#ifndef __XTENSA_API_H__
#define __XTENSA_API_H__
#include <xtensa/hal.h>
#include "xtensa_context.h"
/* Typedef for C-callable interrupt handler function */
typedef void (*xt_handler)(void *);
/* Typedef for C-callable exception handler function */
typedef void (*xt_exc_handler)(XtExcFrame *);
/*
-------------------------------------------------------------------------------
Call this function to set a handler for the specified exception.
n - Exception number (type)
f - Handler function address, NULL to uninstall handler.
The handler will be passed a pointer to the exception frame, which is created
on the stack of the thread that caused the exception.
If the handler returns, the thread context will be restored and the faulting
instruction will be retried. Any values in the exception frame that are
modified by the handler will be restored as part of the context. For details
of the exception frame structure see xtensa_context.h.
-------------------------------------------------------------------------------
*/
extern xt_exc_handler xt_set_exception_handler(int n, xt_exc_handler f);
/*
-------------------------------------------------------------------------------
Call this function to set a handler for the specified interrupt.
n - Interrupt number.
f - Handler function address, NULL to uninstall handler.
arg - Argument to be passed to handler.
-------------------------------------------------------------------------------
*/
extern xt_handler xt_set_interrupt_handler(int n, xt_handler f, void * arg);
/*
-------------------------------------------------------------------------------
Call this function to enable the specified interrupts.
mask - Bit mask of interrupts to be enabled.
Returns the previous state of the interrupt enables.
-------------------------------------------------------------------------------
*/
extern unsigned int xt_ints_on(unsigned int mask);
/*
-------------------------------------------------------------------------------
Call this function to disable the specified interrupts.
mask - Bit mask of interrupts to be disabled.
Returns the previous state of the interrupt enables.
-------------------------------------------------------------------------------
*/
extern unsigned int xt_ints_off(unsigned int mask);
/*
-------------------------------------------------------------------------------
Call this function to set the specified (s/w) interrupt.
-------------------------------------------------------------------------------
*/
static inline void xt_set_intset(unsigned int arg)
{
xthal_set_intset(arg);
}
/*
-------------------------------------------------------------------------------
Call this function to clear the specified (s/w or edge-triggered)
interrupt.
-------------------------------------------------------------------------------
*/
static inline void xt_set_intclear(unsigned int arg)
{
xthal_set_intclear(arg);
}
#endif /* __XTENSA_API_H__ */

@ -0,0 +1,182 @@
/*******************************************************************************
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
Configuration-specific information for Xtensa build. This file must be
included in FreeRTOSConfig.h to properly set up the config-dependent
parameters correctly.
NOTE: To enable thread-safe C library support, XT_USE_THREAD_SAFE_CLIB must
be defined to be > 0 somewhere above or on the command line.
*******************************************************************************/
#ifndef XTENSA_CONFIG_H
#define XTENSA_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <xtensa/hal.h>
#include <xtensa/config/core.h>
#include <xtensa/config/system.h> /* required for XSHAL_CLIB */
#include "xtensa_context.h"
/*-----------------------------------------------------------------------------
* STACK REQUIREMENTS
*
* This section defines the minimum stack size, and the extra space required to
* be allocated for saving coprocessor state and/or C library state information
* (if thread safety is enabled for the C library). The sizes are in bytes.
*
* Stack sizes for individual tasks should be derived from these minima based on
* the maximum call depth of the task and the maximum level of interrupt nesting.
* A minimum stack size is defined by XT_STACK_MIN_SIZE. This minimum is based
* on the requirement for a task that calls nothing else but can be interrupted.
* This assumes that interrupt handlers do not call more than a few levels deep.
* If this is not true, i.e. one or more interrupt handlers make deep calls then
* the minimum must be increased.
*
* If the Xtensa processor configuration includes coprocessors, then space is
* allocated to save the coprocessor state on the stack.
*
* If thread safety is enabled for the C runtime library, (XT_USE_THREAD_SAFE_CLIB
* is defined) then space is allocated to save the C library context in the TCB.
*
* Allocating insufficient stack space is a common source of hard-to-find errors.
* During development, it is best to enable the FreeRTOS stack checking features.
*
* Usage:
*
* XT_USE_THREAD_SAFE_CLIB -- Define this to a nonzero value to enable thread-safe
* use of the C library. This will require extra stack
* space to be allocated for tasks that use the C library
* reentrant functions. See below for more information.
*
* NOTE: The Xtensa toolchain supports multiple C libraries and not all of them
* support thread safety. Check your core configuration to see which C library
* was chosen for your system.
*
* XT_STACK_MIN_SIZE -- The minimum stack size for any task. It is recommended
* that you do not use a stack smaller than this for any
* task. In case you want to use stacks smaller than this
* size, you must verify that the smaller size(s) will work
* under all operating conditions.
*
* XT_STACK_EXTRA -- The amount of extra stack space to allocate for a task
* that does not make C library reentrant calls. Add this
* to the amount of stack space required by the task itself.
*
* XT_STACK_EXTRA_CLIB -- The amount of space to allocate for C library state.
*
-----------------------------------------------------------------------------*/
/* Extra space required for interrupt/exception hooks. */
#ifdef XT_INTEXC_HOOKS
#ifdef __XTENSA_CALL0_ABI__
#define STK_INTEXC_EXTRA 0x200
#else
#define STK_INTEXC_EXTRA 0x180
#endif
#else
#define STK_INTEXC_EXTRA 0
#endif
/* Check C library thread safety support and compute size of C library save area.
For the supported libraries, we enable thread safety by default, and this can
be overridden from the compiler/make command line. */
#if (XSHAL_CLIB == XTHAL_CLIB_NEWLIB) || (XSHAL_CLIB == XTHAL_CLIB_XCLIB)
#ifndef XT_USE_THREAD_SAFE_CLIB
#define XT_USE_THREAD_SAFE_CLIB 1
#endif
#else
#define XT_USE_THREAD_SAFE_CLIB 0
#endif
#if XT_USE_THREAD_SAFE_CLIB > 0u
#if XSHAL_CLIB == XTHAL_CLIB_XCLIB
#define XT_HAVE_THREAD_SAFE_CLIB 1
#if !defined __ASSEMBLER__
#include <sys/reent.h>
#define XT_CLIB_CONTEXT_AREA_SIZE ((sizeof(struct _reent) + 15) + (-16))
#define XT_CLIB_GLOBAL_PTR _reent_ptr
#define _REENT_INIT_PTR _init_reent
#define _impure_ptr _reent_ptr
void _reclaim_reent(void * ptr);
#endif
#elif XSHAL_CLIB == XTHAL_CLIB_NEWLIB
#define XT_HAVE_THREAD_SAFE_CLIB 1
#if !defined __ASSEMBLER__
#include <sys/reent.h>
#define XT_CLIB_CONTEXT_AREA_SIZE ((sizeof(struct _reent) + 15) + (-16))
#define XT_CLIB_GLOBAL_PTR _impure_ptr
#endif
#else
#define XT_HAVE_THREAD_SAFE_CLIB 0
#error The selected C runtime library is not thread safe.
#endif
#else
#define XT_CLIB_CONTEXT_AREA_SIZE 0
#endif
/*------------------------------------------------------------------------------
Extra size -- interrupt frame plus coprocessor save area plus hook space.
NOTE: Make sure XT_INTEXC_HOOKS is undefined unless you really need the hooks.
------------------------------------------------------------------------------*/
#ifdef __XTENSA_CALL0_ABI__
#define XT_XTRA_SIZE (XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x10 + XT_CP_SIZE)
#else
#define XT_XTRA_SIZE (XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x20 + XT_CP_SIZE)
#endif
/*------------------------------------------------------------------------------
Space allocated for user code -- function calls and local variables.
NOTE: This number can be adjusted to suit your needs. You must verify that the
amount of space you reserve is adequate for the worst-case conditions in your
application.
NOTE: The windowed ABI requires more stack, since space has to be reserved
for spilling register windows.
------------------------------------------------------------------------------*/
#ifdef __XTENSA_CALL0_ABI__
#define XT_USER_SIZE 0x200
#else
#define XT_USER_SIZE 0x400
#endif
/* Minimum recommended stack size. */
#define XT_STACK_MIN_SIZE ((XT_XTRA_SIZE + XT_USER_SIZE) / sizeof(unsigned char))
/* OS overhead with and without C library thread context. */
#define XT_STACK_EXTRA (XT_XTRA_SIZE)
#define XT_STACK_EXTRA_CLIB (XT_XTRA_SIZE + XT_CLIB_CONTEXT_AREA_SIZE)
#ifdef __cplusplus
}
#endif
#endif /* XTENSA_CONFIG_H */

@ -0,0 +1,624 @@
/*******************************************************************************
Copyright (c) 2006-2015 Cadence Design Systems Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
XTENSA CONTEXT SAVE AND RESTORE ROUTINES
Low-level Call0 functions for handling generic context save and restore of
registers not specifically addressed by the interrupt vectors and handlers.
Those registers (not handled by these functions) are PC, PS, A0, A1 (SP).
Except for the calls to RTOS functions, this code is generic to Xtensa.
Note that in Call0 ABI, interrupt handlers are expected to preserve the callee-
save regs (A12-A15), which is always the case if the handlers are coded in C.
However A12, A13 are made available as scratch registers for interrupt dispatch
code, so are presumed saved anyway, and are always restored even in Call0 ABI.
Only A14, A15 are truly handled as callee-save regs.
Because Xtensa is a configurable architecture, this port supports all user
generated configurations (except restrictions stated in the release notes).
This is accomplished by conditional compilation using macros and functions
defined in the Xtensa HAL (hardware adaptation layer) for your configuration.
Only the processor state included in your configuration is saved and restored,
including any processor state added by user configuration options or TIE.
*******************************************************************************/
/* Warn nicely if this file gets named with a lowercase .s instead of .S: */
#define NOERROR #
NOERROR: .error "C preprocessor needed for this file: make sure its filename\
ends in uppercase .S, or use xt-xcc's -x assembler-with-cpp option."
#include "xtensa_rtos.h"
#ifdef XT_USE_OVLY
#include <xtensa/overlay_os_asm.h>
#endif
.text
/*******************************************************************************
_xt_context_save
!! MUST BE CALLED ONLY BY 'CALL0' INSTRUCTION !!
Saves all Xtensa processor state except PC, PS, A0, A1 (SP), A12, A13, in the
interrupt stack frame defined in xtensa_rtos.h.
Its counterpart is _xt_context_restore (which also restores A12, A13).
Caller is expected to have saved PC, PS, A0, A1 (SP), A12, A13 in the frame.
This function preserves A12 & A13 in order to provide the caller with 2 scratch
regs that need not be saved over the call to this function. The choice of which
2 regs to provide is governed by xthal_window_spill_nw and xthal_save_extra_nw,
to avoid moving data more than necessary. Caller can assign regs accordingly.
Entry Conditions:
A0 = Return address in caller.
A1 = Stack pointer of interrupted thread or handler ("interruptee").
Original A12, A13 have already been saved in the interrupt stack frame.
Other processor state except PC, PS, A0, A1 (SP), A12, A13, is as at the
point of interruption.
If windowed ABI, PS.EXCM = 1 (exceptions disabled).
Exit conditions:
A0 = Return address in caller.
A1 = Stack pointer of interrupted thread or handler ("interruptee").
A12, A13 as at entry (preserved).
If windowed ABI, PS.EXCM = 1 (exceptions disabled).
*******************************************************************************/
.global _xt_context_save
.type _xt_context_save,@function
.align 4
_xt_context_save:
s32i a2, sp, XT_STK_A2
s32i a3, sp, XT_STK_A3
s32i a4, sp, XT_STK_A4
s32i a5, sp, XT_STK_A5
s32i a6, sp, XT_STK_A6
s32i a7, sp, XT_STK_A7
s32i a8, sp, XT_STK_A8
s32i a9, sp, XT_STK_A9
s32i a10, sp, XT_STK_A10
s32i a11, sp, XT_STK_A11
/*
Call0 ABI callee-saved regs a12-15 do not need to be saved here.
a12-13 are the caller's responsibility so it can use them as scratch.
So only need to save a14-a15 here for Windowed ABI (not Call0).
*/
#ifndef __XTENSA_CALL0_ABI__
s32i a14, sp, XT_STK_A14
s32i a15, sp, XT_STK_A15
#endif
rsr a3, SAR
s32i a3, sp, XT_STK_SAR
#if XCHAL_HAVE_LOOPS
rsr a3, LBEG
s32i a3, sp, XT_STK_LBEG
rsr a3, LEND
s32i a3, sp, XT_STK_LEND
rsr a3, LCOUNT
s32i a3, sp, XT_STK_LCOUNT
#endif
#if XT_USE_SWPRI
/* Save virtual priority mask */
movi a3, _xt_vpri_mask
l32i a3, a3, 0
s32i a3, sp, XT_STK_VPRI
#endif
#if XCHAL_EXTRA_SA_SIZE > 0 || !defined(__XTENSA_CALL0_ABI__)
mov a9, a0 /* preserve ret addr */
#endif
#ifndef __XTENSA_CALL0_ABI__
/*
To spill the reg windows, temp. need pre-interrupt stack ptr and a4-15.
Need to save a9,12,13 temporarily (in frame temps) and recover originals.
Interrupts need to be disabled below XCHAL_EXCM_LEVEL and window overflow
and underflow exceptions disabled (assured by PS.EXCM == 1).
*/
s32i a12, sp, XT_STK_TMP0 /* temp. save stuff in stack frame */
s32i a13, sp, XT_STK_TMP1
s32i a9, sp, XT_STK_TMP2
/*
Save the overlay state if we are supporting overlays. Since we just saved
three registers, we can conveniently use them here. Note that as of now,
overlays only work for windowed calling ABI.
*/
#ifdef XT_USE_OVLY
l32i a9, sp, XT_STK_PC /* recover saved PC */
_xt_overlay_get_state a9, a12, a13
s32i a9, sp, XT_STK_OVLY /* save overlay state */
#endif
l32i a12, sp, XT_STK_A12 /* recover original a9,12,13 */
l32i a13, sp, XT_STK_A13
l32i a9, sp, XT_STK_A9
addi sp, sp, XT_STK_FRMSZ /* restore the interruptee's SP */
call0 xthal_window_spill_nw /* preserves only a4,5,8,9,12,13 */
addi sp, sp, -XT_STK_FRMSZ
l32i a12, sp, XT_STK_TMP0 /* recover stuff from stack frame */
l32i a13, sp, XT_STK_TMP1
l32i a9, sp, XT_STK_TMP2
#endif
#if XCHAL_EXTRA_SA_SIZE > 0
/*
NOTE: Normally the xthal_save_extra_nw macro only affects address
registers a2-a5. It is theoretically possible for Xtensa processor
designers to write TIE that causes more address registers to be
affected, but it is generally unlikely. If that ever happens,
more registers need to be saved/restored around this macro invocation.
Here we assume a9,12,13 are preserved.
Future Xtensa tools releases might limit the regs that can be affected.
*/
addi a2, sp, XT_STK_EXTRA /* where to save it */
# if XCHAL_EXTRA_SA_ALIGN > 16
movi a3, -XCHAL_EXTRA_SA_ALIGN
and a2, a2, a3 /* align dynamically >16 bytes */
# endif
call0 xthal_save_extra_nw /* destroys a0,2,3,4,5 */
#endif
#if XCHAL_EXTRA_SA_SIZE > 0 || !defined(__XTENSA_CALL0_ABI__)
mov a0, a9 /* retrieve ret addr */
#endif
ret
/*******************************************************************************
_xt_context_restore
!! MUST BE CALLED ONLY BY 'CALL0' INSTRUCTION !!
Restores all Xtensa processor state except PC, PS, A0, A1 (SP) (and in Call0
ABI, A14, A15 which are preserved by all interrupt handlers) from an interrupt
stack frame defined in xtensa_rtos.h .
Its counterpart is _xt_context_save (whose caller saved A12, A13).
Caller is responsible to restore PC, PS, A0, A1 (SP).
Entry Conditions:
A0 = Return address in caller.
A1 = Stack pointer of interrupted thread or handler ("interruptee").
Exit conditions:
A0 = Return address in caller.
A1 = Stack pointer of interrupted thread or handler ("interruptee").
Other processor state except PC, PS, A0, A1 (SP), is as at the point
of interruption.
*******************************************************************************/
.global _xt_context_restore
.type _xt_context_restore,@function
.align 4
_xt_context_restore:
#if XCHAL_EXTRA_SA_SIZE > 0
/*
NOTE: Normally the xthal_restore_extra_nw macro only affects address
registers a2-a5. It is theoretically possible for Xtensa processor
designers to write TIE that causes more address registers to be
affected, but it is generally unlikely. If that ever happens,
more registers need to be saved/restored around this macro invocation.
Here we only assume a13 is preserved.
Future Xtensa tools releases might limit the regs that can be affected.
*/
mov a13, a0 /* preserve ret addr */
addi a2, sp, XT_STK_EXTRA /* where to find it */
# if XCHAL_EXTRA_SA_ALIGN > 16
movi a3, -XCHAL_EXTRA_SA_ALIGN
and a2, a2, a3 /* align dynamically >16 bytes */
# endif
call0 xthal_restore_extra_nw /* destroys a0,2,3,4,5 */
mov a0, a13 /* retrieve ret addr */
#endif
#if XCHAL_HAVE_LOOPS
l32i a2, sp, XT_STK_LBEG
l32i a3, sp, XT_STK_LEND
wsr a2, LBEG
l32i a2, sp, XT_STK_LCOUNT
wsr a3, LEND
wsr a2, LCOUNT
#endif
#ifdef XT_USE_OVLY
/*
If we are using overlays, this is a good spot to check if we need
to restore an overlay for the incoming task. Here we have a bunch
of registers to spare. Note that this step is going to use a few
bytes of storage below SP (SP-20 to SP-32) if an overlay is going
to be restored.
*/
l32i a2, sp, XT_STK_PC /* retrieve PC */
l32i a3, sp, XT_STK_PS /* retrieve PS */
l32i a4, sp, XT_STK_OVLY /* retrieve overlay state */
l32i a5, sp, XT_STK_A1 /* retrieve stack ptr */
_xt_overlay_check_map a2, a3, a4, a5, a6
s32i a2, sp, XT_STK_PC /* save updated PC */
s32i a3, sp, XT_STK_PS /* save updated PS */
#endif
#ifdef XT_USE_SWPRI
/* Restore virtual interrupt priority and interrupt enable */
movi a3, _xt_intdata
l32i a4, a3, 0 /* a4 = _xt_intenable */
l32i a5, sp, XT_STK_VPRI /* a5 = saved _xt_vpri_mask */
and a4, a4, a5
wsr a4, INTENABLE /* update INTENABLE */
s32i a5, a3, 4 /* restore _xt_vpri_mask */
#endif
l32i a3, sp, XT_STK_SAR
l32i a2, sp, XT_STK_A2
wsr a3, SAR
l32i a3, sp, XT_STK_A3
l32i a4, sp, XT_STK_A4
l32i a5, sp, XT_STK_A5
l32i a6, sp, XT_STK_A6
l32i a7, sp, XT_STK_A7
l32i a8, sp, XT_STK_A8
l32i a9, sp, XT_STK_A9
l32i a10, sp, XT_STK_A10
l32i a11, sp, XT_STK_A11
/*
Call0 ABI callee-saved regs a12-15 do not need to be restored here.
However a12-13 were saved for scratch before XT_RTOS_INT_ENTER(),
so need to be restored anyway, despite being callee-saved in Call0.
*/
l32i a12, sp, XT_STK_A12
l32i a13, sp, XT_STK_A13
#ifndef __XTENSA_CALL0_ABI__
l32i a14, sp, XT_STK_A14
l32i a15, sp, XT_STK_A15
#endif
ret
/*******************************************************************************
_xt_coproc_init
Initializes global co-processor management data, setting all co-processors
to "unowned". Leaves CPENABLE as it found it (does NOT clear it).
Called during initialization of the RTOS, before any threads run.
This may be called from normal Xtensa single-threaded application code which
might use co-processors. The Xtensa run-time initialization enables all
co-processors. They must remain enabled here, else a co-processor exception
might occur outside of a thread, which the exception handler doesn't expect.
Entry Conditions:
Xtensa single-threaded run-time environment is in effect.
No thread is yet running.
Exit conditions:
None.
Obeys ABI conventions per prototype:
void _xt_coproc_init(void)
*******************************************************************************/
#if XCHAL_CP_NUM > 0
.global _xt_coproc_init
.type _xt_coproc_init,@function
.align 4
_xt_coproc_init:
ENTRY0
/* Initialize thread co-processor ownerships to 0 (unowned). */
movi a2, _xt_coproc_owner_sa /* a2 = base of owner array */
addi a3, a2, XCHAL_CP_MAX << 2 /* a3 = top+1 of owner array */
movi a4, 0 /* a4 = 0 (unowned) */
1: s32i a4, a2, 0
addi a2, a2, 4
bltu a2, a3, 1b
RET0
#endif
/*******************************************************************************
_xt_coproc_release
Releases any and all co-processors owned by a given thread. The thread is
identified by it's co-processor state save area defined in xtensa_context.h .
Must be called before a thread's co-proc save area is deleted to avoid
memory corruption when the exception handler tries to save the state.
May be called when a thread terminates or completes but does not delete
the co-proc save area, to avoid the exception handler having to save the
thread's co-proc state before another thread can use it (optimization).
Entry Conditions:
A2 = Pointer to base of co-processor state save area.
Exit conditions:
None.
Obeys ABI conventions per prototype:
void _xt_coproc_release(void * coproc_sa_base)
*******************************************************************************/
#if XCHAL_CP_NUM > 0
.global _xt_coproc_release
.type _xt_coproc_release,@function
.align 4
_xt_coproc_release:
ENTRY0 /* a2 = base of save area */
movi a3, _xt_coproc_owner_sa /* a3 = base of owner array */
addi a4, a3, XCHAL_CP_MAX << 2 /* a4 = top+1 of owner array */
movi a5, 0 /* a5 = 0 (unowned) */
rsil a6, XCHAL_EXCM_LEVEL /* lock interrupts */
1: l32i a7, a3, 0 /* a7 = owner at a3 */
bne a2, a7, 2f /* if (coproc_sa_base == owner) */
s32i a5, a3, 0 /* owner = unowned */
2: addi a3, a3, 1<<2 /* a3 = next entry in owner array */
bltu a3, a4, 1b /* repeat until end of array */
3: wsr a6, PS /* restore interrupts */
RET0
#endif
/*******************************************************************************
_xt_coproc_savecs
If there is a current thread and it has a coprocessor state save area, then
save all callee-saved state into this area. This function is called from the
solicited context switch handler. It calls a system-specific function to get
the coprocessor save area base address.
Entry conditions:
- The thread being switched out is still the current thread.
- CPENABLE state reflects which coprocessors are active.
- Registers have been saved/spilled already.
Exit conditions:
- All necessary CP callee-saved state has been saved.
- Registers a2-a7, a13-a15 have been trashed.
Must be called from assembly code only, using CALL0.
*******************************************************************************/
#if XCHAL_CP_NUM > 0
.extern _xt_coproc_sa_offset /* external reference */
.global _xt_coproc_savecs
.type _xt_coproc_savecs,@function
.align 4
_xt_coproc_savecs:
/* At entry, CPENABLE should be showing which CPs are enabled. */
rsr a2, CPENABLE /* a2 = which CPs are enabled */
beqz a2, .Ldone /* quick exit if none */
mov a14, a0 /* save return address */
call0 XT_RTOS_CP_STATE /* get address of CP save area */
mov a0, a14 /* restore return address */
beqz a15, .Ldone /* if none then nothing to do */
s16i a2, a15, XT_CP_CS_ST /* save mask of CPs being stored */
movi a13, _xt_coproc_sa_offset /* array of CP save offsets */
l32i a15, a15, XT_CP_ASA /* a15 = base of aligned save area */
#if XCHAL_CP0_SA_SIZE
bbci.l a2, 0, 2f /* CP 0 not enabled */
l32i a14, a13, 0 /* a14 = _xt_coproc_sa_offset[0] */
add a3, a14, a15 /* a3 = save area for CP 0 */
xchal_cp0_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP1_SA_SIZE
bbci.l a2, 1, 2f /* CP 1 not enabled */
l32i a14, a13, 4 /* a14 = _xt_coproc_sa_offset[1] */
add a3, a14, a15 /* a3 = save area for CP 1 */
xchal_cp1_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP2_SA_SIZE
bbci.l a2, 2, 2f
l32i a14, a13, 8
add a3, a14, a15
xchal_cp2_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP3_SA_SIZE
bbci.l a2, 3, 2f
l32i a14, a13, 12
add a3, a14, a15
xchal_cp3_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP4_SA_SIZE
bbci.l a2, 4, 2f
l32i a14, a13, 16
add a3, a14, a15
xchal_cp4_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP5_SA_SIZE
bbci.l a2, 5, 2f
l32i a14, a13, 20
add a3, a14, a15
xchal_cp5_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP6_SA_SIZE
bbci.l a2, 6, 2f
l32i a14, a13, 24
add a3, a14, a15
xchal_cp6_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP7_SA_SIZE
bbci.l a2, 7, 2f
l32i a14, a13, 28
add a3, a14, a15
xchal_cp7_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
.Ldone:
ret
#endif
/*******************************************************************************
_xt_coproc_restorecs
Restore any callee-saved coprocessor state for the incoming thread.
This function is called from coprocessor exception handling, when giving
ownership to a thread that solicited a context switch earlier. It calls a
system-specific function to get the coprocessor save area base address.
Entry conditions:
- The incoming thread is set as the current thread.
- CPENABLE is set up correctly for all required coprocessors.
- a2 = mask of coprocessors to be restored.
Exit conditions:
- All necessary CP callee-saved state has been restored.
- CPENABLE - unchanged.
- Registers a2-a7, a13-a15 have been trashed.
Must be called from assembly code only, using CALL0.
*******************************************************************************/
#if XCHAL_CP_NUM > 0
.global _xt_coproc_restorecs
.type _xt_coproc_restorecs,@function
.align 4
_xt_coproc_restorecs:
mov a14, a0 /* save return address */
call0 XT_RTOS_CP_STATE /* get address of CP save area */
mov a0, a14 /* restore return address */
beqz a15, .Ldone2 /* if none then nothing to do */
l16ui a3, a15, XT_CP_CS_ST /* a3 = which CPs have been saved */
xor a3, a3, a2 /* clear the ones being restored */
s32i a3, a15, XT_CP_CS_ST /* update saved CP mask */
movi a13, _xt_coproc_sa_offset /* array of CP save offsets */
l32i a15, a15, XT_CP_ASA /* a15 = base of aligned save area */
#if XCHAL_CP0_SA_SIZE
bbci.l a2, 0, 2f /* CP 0 not enabled */
l32i a14, a13, 0 /* a14 = _xt_coproc_sa_offset[0] */
add a3, a14, a15 /* a3 = save area for CP 0 */
xchal_cp0_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP1_SA_SIZE
bbci.l a2, 1, 2f /* CP 1 not enabled */
l32i a14, a13, 4 /* a14 = _xt_coproc_sa_offset[1] */
add a3, a14, a15 /* a3 = save area for CP 1 */
xchal_cp1_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP2_SA_SIZE
bbci.l a2, 2, 2f
l32i a14, a13, 8
add a3, a14, a15
xchal_cp2_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP3_SA_SIZE
bbci.l a2, 3, 2f
l32i a14, a13, 12
add a3, a14, a15
xchal_cp3_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP4_SA_SIZE
bbci.l a2, 4, 2f
l32i a14, a13, 16
add a3, a14, a15
xchal_cp4_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP5_SA_SIZE
bbci.l a2, 5, 2f
l32i a14, a13, 20
add a3, a14, a15
xchal_cp5_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP6_SA_SIZE
bbci.l a2, 6, 2f
l32i a14, a13, 24
add a3, a14, a15
xchal_cp6_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP7_SA_SIZE
bbci.l a2, 7, 2f
l32i a14, a13, 28
add a3, a14, a15
xchal_cp7_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
.Ldone2:
ret
#endif

@ -0,0 +1,350 @@
/*******************************************************************************
Copyright (c) 2006-2015 Cadence Design Systems Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
XTENSA CONTEXT FRAMES AND MACROS FOR RTOS ASSEMBLER SOURCES
This header contains definitions and macros for use primarily by Xtensa
RTOS assembly coded source files. It includes and uses the Xtensa hardware
abstraction layer (HAL) to deal with config specifics. It may also be
included in C source files.
!! Supports only Xtensa Exception Architecture 2 (XEA2). XEA1 not supported. !!
NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes.
*******************************************************************************/
#ifndef XTENSA_CONTEXT_H
#define XTENSA_CONTEXT_H
#ifdef __ASSEMBLER__
#include <xtensa/coreasm.h>
#endif
#include <xtensa/config/tie.h>
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
/* Align a value up to nearest n-byte boundary, where n is a power of 2. */
#define ALIGNUP(n, val) (((val) + (n)-1) & -(n))
/*
-------------------------------------------------------------------------------
Macros that help define structures for both C and assembler.
-------------------------------------------------------------------------------
*/
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
#define STRUCT_BEGIN .pushsection .text; .struct 0
#define STRUCT_FIELD(ctype,size,asname,name) asname: .space size
#define STRUCT_AFIELD(ctype,size,asname,name,n) asname: .space (size)*(n)
#define STRUCT_END(sname) sname##Size:; .popsection
#else
#define STRUCT_BEGIN typedef struct {
#define STRUCT_FIELD(ctype,size,asname,name) ctype name;
#define STRUCT_AFIELD(ctype,size,asname,name,n) ctype name[n];
#define STRUCT_END(sname) } sname;
#endif //_ASMLANGUAGE || __ASSEMBLER__
/*
-------------------------------------------------------------------------------
INTERRUPT/EXCEPTION STACK FRAME FOR A THREAD OR NESTED INTERRUPT
A stack frame of this structure is allocated for any interrupt or exception.
It goes on the current stack. If the RTOS has a system stack for handling
interrupts, every thread stack must allow space for just one interrupt stack
frame, then nested interrupt stack frames go on the system stack.
The frame includes basic registers (explicit) and "extra" registers introduced
by user TIE or the use of the MAC16 option in the user's Xtensa config.
The frame size is minimized by omitting regs not applicable to user's config.
For Windowed ABI, this stack frame includes the interruptee's base save area,
another base save area to manage gcc nested functions, and a little temporary
space to help manage the spilling of the register windows.
-------------------------------------------------------------------------------
*/
STRUCT_BEGIN
STRUCT_FIELD (long, 4, XT_STK_EXIT, exit) /* exit point for dispatch */
STRUCT_FIELD (long, 4, XT_STK_PC, pc) /* return PC */
STRUCT_FIELD (long, 4, XT_STK_PS, ps) /* return PS */
STRUCT_FIELD (long, 4, XT_STK_A0, a0)
STRUCT_FIELD (long, 4, XT_STK_A1, a1) /* stack pointer before interrupt */
STRUCT_FIELD (long, 4, XT_STK_A2, a2)
STRUCT_FIELD (long, 4, XT_STK_A3, a3)
STRUCT_FIELD (long, 4, XT_STK_A4, a4)
STRUCT_FIELD (long, 4, XT_STK_A5, a5)
STRUCT_FIELD (long, 4, XT_STK_A6, a6)
STRUCT_FIELD (long, 4, XT_STK_A7, a7)
STRUCT_FIELD (long, 4, XT_STK_A8, a8)
STRUCT_FIELD (long, 4, XT_STK_A9, a9)
STRUCT_FIELD (long, 4, XT_STK_A10, a10)
STRUCT_FIELD (long, 4, XT_STK_A11, a11)
STRUCT_FIELD (long, 4, XT_STK_A12, a12)
STRUCT_FIELD (long, 4, XT_STK_A13, a13)
STRUCT_FIELD (long, 4, XT_STK_A14, a14)
STRUCT_FIELD (long, 4, XT_STK_A15, a15)
STRUCT_FIELD (long, 4, XT_STK_SAR, sar)
STRUCT_FIELD (long, 4, XT_STK_EXCCAUSE, exccause)
STRUCT_FIELD (long, 4, XT_STK_EXCVADDR, excvaddr)
#if XCHAL_HAVE_LOOPS
STRUCT_FIELD (long, 4, XT_STK_LBEG, lbeg)
STRUCT_FIELD (long, 4, XT_STK_LEND, lend)
STRUCT_FIELD (long, 4, XT_STK_LCOUNT, lcount)
#endif
#ifndef __XTENSA_CALL0_ABI__
/* Temporary space for saving stuff during window spill */
STRUCT_FIELD (long, 4, XT_STK_TMP0, tmp0)
STRUCT_FIELD (long, 4, XT_STK_TMP1, tmp1)
STRUCT_FIELD (long, 4, XT_STK_TMP2, tmp2)
#endif
#ifdef XT_USE_SWPRI
/* Storage for virtual priority mask */
STRUCT_FIELD (long, 4, XT_STK_VPRI, vpri)
#endif
#ifdef XT_USE_OVLY
/* Storage for overlay state */
STRUCT_FIELD (long, 4, XT_STK_OVLY, ovly)
#endif
STRUCT_END(XtExcFrame)
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
#define XT_STK_NEXT1 XtExcFrameSize
#else
#define XT_STK_NEXT1 sizeof(XtExcFrame)
#endif
/* Allocate extra storage if needed */
#if XCHAL_EXTRA_SA_SIZE != 0
#if XCHAL_EXTRA_SA_ALIGN <= 16
#define XT_STK_EXTRA ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1)
#else
/* If need more alignment than stack, add space for dynamic alignment */
#define XT_STK_EXTRA (ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1) + XCHAL_EXTRA_SA_ALIGN)
#endif
#define XT_STK_NEXT2 (XT_STK_EXTRA + XCHAL_EXTRA_SA_SIZE)
#else
#define XT_STK_NEXT2 XT_STK_NEXT1
#endif
/*
-------------------------------------------------------------------------------
This is the frame size. Add space for 4 registers (interruptee's base save
area) and some space for gcc nested functions if any.
-------------------------------------------------------------------------------
*/
#define XT_STK_FRMSZ (ALIGNUP(0x10, XT_STK_NEXT2) + 0x20)
/*
-------------------------------------------------------------------------------
SOLICITED STACK FRAME FOR A THREAD
A stack frame of this structure is allocated whenever a thread enters the
RTOS kernel intentionally (and synchronously) to submit to thread scheduling.
It goes on the current thread's stack.
The solicited frame only includes registers that are required to be preserved
by the callee according to the compiler's ABI conventions, some space to save
the return address for returning to the caller, and the caller's PS register.
For Windowed ABI, this stack frame includes the caller's base save area.
Note on XT_SOL_EXIT field:
It is necessary to distinguish a solicited from an interrupt stack frame.
This field corresponds to XT_STK_EXIT in the interrupt stack frame and is
always at the same offset (0). It can be written with a code (usually 0)
to distinguish a solicted frame from an interrupt frame. An RTOS port may
opt to ignore this field if it has another way of distinguishing frames.
-------------------------------------------------------------------------------
*/
STRUCT_BEGIN
#ifdef __XTENSA_CALL0_ABI__
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
STRUCT_FIELD (long, 4, XT_SOL_PC, pc)
STRUCT_FIELD (long, 4, XT_SOL_PS, ps)
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next)
STRUCT_FIELD (long, 4, XT_SOL_A12, a12) /* should be on 16-byte alignment */
STRUCT_FIELD (long, 4, XT_SOL_A13, a13)
STRUCT_FIELD (long, 4, XT_SOL_A14, a14)
STRUCT_FIELD (long, 4, XT_SOL_A15, a15)
#else
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
STRUCT_FIELD (long, 4, XT_SOL_PC, pc)
STRUCT_FIELD (long, 4, XT_SOL_PS, ps)
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next)
STRUCT_FIELD (long, 4, XT_SOL_A0, a0) /* should be on 16-byte alignment */
STRUCT_FIELD (long, 4, XT_SOL_A1, a1)
STRUCT_FIELD (long, 4, XT_SOL_A2, a2)
STRUCT_FIELD (long, 4, XT_SOL_A3, a3)
#endif
STRUCT_END(XtSolFrame)
/* Size of solicited stack frame */
#define XT_SOL_FRMSZ ALIGNUP(0x10, XtSolFrameSize)
/*
-------------------------------------------------------------------------------
CO-PROCESSOR STATE SAVE AREA FOR A THREAD
The RTOS must provide an area per thread to save the state of co-processors
when that thread does not have control. Co-processors are context-switched
lazily (on demand) only when a new thread uses a co-processor instruction,
otherwise a thread retains ownership of the co-processor even when it loses
control of the processor. An Xtensa co-processor exception is triggered when
any co-processor instruction is executed by a thread that is not the owner,
and the context switch of that co-processor is then peformed by the handler.
Ownership represents which thread's state is currently in the co-processor.
Co-processors may not be used by interrupt or exception handlers. If an
co-processor instruction is executed by an interrupt or exception handler,
the co-processor exception handler will trigger a kernel panic and freeze.
This restriction is introduced to reduce the overhead of saving and restoring
co-processor state (which can be quite large) and in particular remove that
overhead from interrupt handlers.
The co-processor state save area may be in any convenient per-thread location
such as in the thread control block or above the thread stack area. It need
not be in the interrupt stack frame since interrupts don't use co-processors.
Along with the save area for each co-processor, two bitmasks with flags per
co-processor (laid out as in the CPENABLE reg) help manage context-switching
co-processors as efficiently as possible:
XT_CPENABLE
The contents of a non-running thread's CPENABLE register.
It represents the co-processors owned (and whose state is still needed)
by the thread. When a thread is preempted, its CPENABLE is saved here.
When a thread solicits a context-swtich, its CPENABLE is cleared - the
compiler has saved the (caller-saved) co-proc state if it needs to.
When a non-running thread loses ownership of a CP, its bit is cleared.
When a thread runs, it's XT_CPENABLE is loaded into the CPENABLE reg.
Avoids co-processor exceptions when no change of ownership is needed.
XT_CPSTORED
A bitmask with the same layout as CPENABLE, a bit per co-processor.
Indicates whether the state of each co-processor is saved in the state
save area. When a thread enters the kernel, only the state of co-procs
still enabled in CPENABLE is saved. When the co-processor exception
handler assigns ownership of a co-processor to a thread, it restores
the saved state only if this bit is set, and clears this bit.
XT_CP_CS_ST
A bitmask with the same layout as CPENABLE, a bit per co-processor.
Indicates whether callee-saved state is saved in the state save area.
Callee-saved state is saved by itself on a solicited context switch,
and restored when needed by the coprocessor exception handler.
Unsolicited switches will cause the entire coprocessor to be saved
when necessary.
XT_CP_ASA
Pointer to the aligned save area. Allows it to be aligned more than
the overall save area (which might only be stack-aligned or TCB-aligned).
Especially relevant for Xtensa cores configured with a very large data
path that requires alignment greater than 16 bytes (ABI stack alignment).
-------------------------------------------------------------------------------
*/
#if XCHAL_CP_NUM > 0
/* Offsets of each coprocessor save area within the 'aligned save area': */
#define XT_CP0_SA 0
#define XT_CP1_SA ALIGNUP(XCHAL_CP1_SA_ALIGN, XT_CP0_SA + XCHAL_CP0_SA_SIZE)
#define XT_CP2_SA ALIGNUP(XCHAL_CP2_SA_ALIGN, XT_CP1_SA + XCHAL_CP1_SA_SIZE)
#define XT_CP3_SA ALIGNUP(XCHAL_CP3_SA_ALIGN, XT_CP2_SA + XCHAL_CP2_SA_SIZE)
#define XT_CP4_SA ALIGNUP(XCHAL_CP4_SA_ALIGN, XT_CP3_SA + XCHAL_CP3_SA_SIZE)
#define XT_CP5_SA ALIGNUP(XCHAL_CP5_SA_ALIGN, XT_CP4_SA + XCHAL_CP4_SA_SIZE)
#define XT_CP6_SA ALIGNUP(XCHAL_CP6_SA_ALIGN, XT_CP5_SA + XCHAL_CP5_SA_SIZE)
#define XT_CP7_SA ALIGNUP(XCHAL_CP7_SA_ALIGN, XT_CP6_SA + XCHAL_CP6_SA_SIZE)
#define XT_CP_SA_SIZE ALIGNUP(16, XT_CP7_SA + XCHAL_CP7_SA_SIZE)
/* Offsets within the overall save area: */
#define XT_CPENABLE 0 /* (2 bytes) coprocessors active for this thread */
#define XT_CPSTORED 2 /* (2 bytes) coprocessors saved for this thread */
#define XT_CP_CS_ST 4 /* (2 bytes) coprocessor callee-saved regs stored for this thread */
#define XT_CP_ASA 8 /* (4 bytes) ptr to aligned save area */
/* Overall size allows for dynamic alignment: */
#define XT_CP_SIZE (12 + XT_CP_SA_SIZE + XCHAL_TOTAL_SA_ALIGN)
#else
#define XT_CP_SIZE 0
#endif
/*
-------------------------------------------------------------------------------
MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN
Convenient where the frame size requirements are the same for both ABIs.
ENTRY(sz), RET(sz) are for framed functions (have locals or make calls).
ENTRY0, RET0 are for frameless functions (no locals, no calls).
where size = size of stack frame in bytes (must be >0 and aligned to 16).
For framed functions the frame is created and the return address saved at
base of frame (Call0 ABI) or as determined by hardware (Windowed ABI).
For frameless functions, there is no frame and return address remains in a0.
Note: Because CPP macros expand to a single line, macros requiring multi-line
expansions are implemented as assembler macros.
-------------------------------------------------------------------------------
*/
#ifdef __ASSEMBLER__
#ifdef __XTENSA_CALL0_ABI__
/* Call0 */
#define ENTRY(sz) entry1 sz
.macro entry1 size=0x10
addi sp, sp, -\size
s32i a0, sp, 0
.endm
#define ENTRY0
#define RET(sz) ret1 sz
.macro ret1 size=0x10
l32i a0, sp, 0
addi sp, sp, \size
ret
.endm
#define RET0 ret
#else
/* Windowed */
#define ENTRY(sz) entry sp, sz
#define ENTRY0 entry sp, 0x10
#define RET(sz) retw
#define RET0 retw
#endif
#endif
#endif /* XTENSA_CONTEXT_H */

@ -0,0 +1,65 @@
/*******************************************************************************
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
XTENSA INITIALIZATION ROUTINES CODED IN C
This file contains miscellaneous Xtensa RTOS-generic initialization functions
that are implemented in C.
*******************************************************************************/
#ifdef XT_BOARD
#include <xtensa/xtbsp.h>
#endif
#include "xtensa_rtos.h"
#ifdef XT_RTOS_TIMER_INT
unsigned _xt_tick_divisor = 0; /* cached number of cycles per tick */
/*
Compute and initialize at run-time the tick divisor (the number of
processor clock cycles in an RTOS tick, used to set the tick timer).
Called when the processor clock frequency is not known at compile-time.
*/
void _xt_tick_divisor_init(void)
{
#ifdef XT_CLOCK_FREQ
_xt_tick_divisor = (XT_CLOCK_FREQ / XT_TICK_PER_SEC);
#else
#ifdef XT_BOARD
_xt_tick_divisor = xtbsp_clock_freq_hz() / XT_TICK_PER_SEC;
#else
#error "No way to obtain processor clock frequency"
#endif /* XT_BOARD */
#endif /* XT_CLOCK_FREQ */
}
#endif /* XT_RTOS_TIMER_INT */

@ -0,0 +1,132 @@
/*******************************************************************************
Copyright (c) 2006-2015 Cadence Design Systems Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/
/******************************************************************************
Xtensa-specific interrupt and exception functions for RTOS ports.
Also see xtensa_intr_asm.S.
******************************************************************************/
#include <stdlib.h>
#include <xtensa/config/core.h>
#include "xtensa_api.h"
#if XCHAL_HAVE_EXCEPTIONS
/* Handler table is in xtensa_intr_asm.S */
extern xt_exc_handler _xt_exception_table[XCHAL_EXCCAUSE_NUM];
/*
Default handler for unhandled exceptions.
*/
void xt_unhandled_exception(XtExcFrame *frame)
{
exit(-1);
}
/*
This function registers a handler for the specified exception.
The function returns the address of the previous handler.
On error, it returns 0.
*/
xt_exc_handler xt_set_exception_handler(int n, xt_exc_handler f)
{
xt_exc_handler old;
if( n < 0 || n >= XCHAL_EXCCAUSE_NUM )
return 0; /* invalid exception number */
old = _xt_exception_table[n];
if (f) {
_xt_exception_table[n] = f;
}
else {
_xt_exception_table[n] = &xt_unhandled_exception;
}
return ((old == &xt_unhandled_exception) ? 0 : old);
}
#endif
#if XCHAL_HAVE_INTERRUPTS
/* Handler table is in xtensa_intr_asm.S */
typedef struct xt_handler_table_entry {
void * handler;
void * arg;
} xt_handler_table_entry;
extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS];
/*
Default handler for unhandled interrupts.
*/
void xt_unhandled_interrupt(void * arg)
{
exit(-1);
}
/*
This function registers a handler for the specified interrupt. The "arg"
parameter specifies the argument to be passed to the handler when it is
invoked. The function returns the address of the previous handler.
On error, it returns 0.
*/
xt_handler xt_set_interrupt_handler(int n, xt_handler f, void * arg)
{
xt_handler_table_entry * entry;
xt_handler old;
if( n < 0 || n >= XCHAL_NUM_INTERRUPTS )
return 0; /* invalid interrupt number */
if( Xthal_intlevel[n] > XCHAL_EXCM_LEVEL )
return 0; /* priority level too high to safely handle in C */
entry = _xt_interrupt_table + n;
old = entry->handler;
if (f) {
entry->handler = f;
entry->arg = arg;
}
else {
entry->handler = &xt_unhandled_interrupt;
entry->arg = (void*)n;
}
return ((old == &xt_unhandled_interrupt) ? 0 : old);
}
#endif /* XCHAL_HAVE_INTERRUPTS */

@ -0,0 +1,179 @@
/*******************************************************************************
Copyright (c) 2006-2015 Cadence Design Systems Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/
/******************************************************************************
Xtensa interrupt handling data and assembly routines.
Also see xtensa_intr.c and xtensa_vectors.S.
******************************************************************************/
#include <xtensa/hal.h>
#include <xtensa/config/core.h>
#include "xtensa_context.h"
#if XCHAL_HAVE_INTERRUPTS
/*
-------------------------------------------------------------------------------
INTENABLE virtualization information.
-------------------------------------------------------------------------------
*/
.data
.global _xt_intdata
.align 8
_xt_intdata:
.global _xt_intenable
.type _xt_intenable,@object
.size _xt_intenable,4
.global _xt_vpri_mask
.type _xt_vpri_mask,@object
.size _xt_vpri_mask,4
_xt_intenable: .word 0 /* Virtual INTENABLE */
_xt_vpri_mask: .word 0xFFFFFFFF /* Virtual priority mask */
/*
-------------------------------------------------------------------------------
Table of C-callable interrupt handlers for each interrupt. Note that not all
slots can be filled, because interrupts at level > EXCM_LEVEL will not be
dispatched to a C handler by default.
-------------------------------------------------------------------------------
*/
.data
.global _xt_interrupt_table
.align 8
_xt_interrupt_table:
.set i, 0
.rept XCHAL_NUM_INTERRUPTS
.word xt_unhandled_interrupt /* handler address */
.word i /* handler arg (default: intnum) */
.set i, i+1
.endr
#endif /* XCHAL_HAVE_INTERRUPTS */
#if XCHAL_HAVE_EXCEPTIONS
/*
-------------------------------------------------------------------------------
Table of C-callable exception handlers for each exception. Note that not all
slots will be active, because some exceptions (e.g. coprocessor exceptions)
are always handled by the OS and cannot be hooked by user handlers.
-------------------------------------------------------------------------------
*/
.data
.global _xt_exception_table
.align 4
_xt_exception_table:
.rept XCHAL_EXCCAUSE_NUM
.word xt_unhandled_exception /* handler address */
.endr
#endif
/*
-------------------------------------------------------------------------------
unsigned int xt_ints_on ( unsigned int mask )
Enables a set of interrupts. Does not simply set INTENABLE directly, but
computes it as a function of the current virtual priority.
Can be called from interrupt handlers.
-------------------------------------------------------------------------------
*/
.text
.align 4
.global xt_ints_on
.type xt_ints_on,@function
xt_ints_on:
ENTRY0
#if XCHAL_HAVE_INTERRUPTS
movi a3, 0
movi a4, _xt_intdata
xsr a3, INTENABLE /* Disables all interrupts */
rsync
l32i a3, a4, 0 /* a3 = _xt_intenable */
l32i a6, a4, 4 /* a6 = _xt_vpri_mask */
or a5, a3, a2 /* a5 = _xt_intenable | mask */
s32i a5, a4, 0 /* _xt_intenable |= mask */
and a5, a5, a6 /* a5 = _xt_intenable & _xt_vpri_mask */
wsr a5, INTENABLE /* Reenable interrupts */
mov a2, a3 /* Previous mask */
#else
movi a2, 0 /* Return zero */
#endif
RET0
.size xt_ints_on, . - xt_ints_on
/*
-------------------------------------------------------------------------------
unsigned int xt_ints_off ( unsigned int mask )
Disables a set of interrupts. Does not simply set INTENABLE directly,
but computes it as a function of the current virtual priority.
Can be called from interrupt handlers.
-------------------------------------------------------------------------------
*/
.text
.align 4
.global xt_ints_off
.type xt_ints_off,@function
xt_ints_off:
ENTRY0
#if XCHAL_HAVE_INTERRUPTS
movi a3, 0
movi a4, _xt_intdata
xsr a3, INTENABLE /* Disables all interrupts */
rsync
l32i a3, a4, 0 /* a3 = _xt_intenable */
l32i a6, a4, 4 /* a6 = _xt_vpri_mask */
or a5, a3, a2 /* a5 = _xt_intenable | mask */
xor a5, a5, a2 /* a5 = _xt_intenable & ~mask */
s32i a5, a4, 0 /* _xt_intenable &= ~mask */
and a5, a5, a6 /* a5 = _xt_intenable & _xt_vpri_mask */
wsr a5, INTENABLE /* Reenable interrupts */
mov a2, a3 /* Previous mask */
#else
movi a2, 0 /* return zero */
#endif
RET0
.size xt_ints_off, . - xt_ints_off

@ -0,0 +1,67 @@
// xtensa_overlay_os_hook.c -- Overlay manager OS hooks for FreeRTOS.
// Copyright (c) 2015-2015 Cadence Design Systems Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "FreeRTOS.h"
#include "semphr.h"
#if configUSE_MUTEX
/* Mutex object that controls access to the overlay. Currently only one
* overlay region is supported so one mutex suffices.
*/
static SemaphoreHandle_t xt_overlay_mutex;
/* This function should be overridden to provide OS specific init such
* as the creation of a mutex lock that can be used for overlay locking.
* Typically this mutex would be set up with priority inheritance. See
* overlay manager documentation for more details.
*/
void xt_overlay_init_os(void)
{
/* Create the mutex for overlay access. Priority inheritance is
* required.
*/
xt_overlay_mutex = xSemaphoreCreateMutex();
}
/* This function locks access to shared overlay resources, typically
* by acquiring a mutex.
*/
void xt_overlay_lock(void)
{
xSemaphoreTake(xt_overlay_mutex, 0);
}
/* This function releases access to shared overlay resources, typically
* by unlocking a mutex.
*/
void xt_overlay_unlock(void)
{
xSemaphoreGive(xt_overlay_mutex);
}
#endif

@ -0,0 +1,233 @@
/*******************************************************************************
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
RTOS-SPECIFIC INFORMATION FOR XTENSA RTOS ASSEMBLER SOURCES
(FreeRTOS Port)
This header is the primary glue between generic Xtensa RTOS support
sources and a specific RTOS port for Xtensa. It contains definitions
and macros for use primarily by Xtensa assembly coded source files.
Macros in this header map callouts from generic Xtensa files to specific
RTOS functions. It may also be included in C source files.
Xtensa RTOS ports support all RTOS-compatible configurations of the Xtensa
architecture, using the Xtensa hardware abstraction layer (HAL) to deal
with configuration specifics.
Should be included by all Xtensa generic and RTOS port-specific sources.
*******************************************************************************/
#ifndef XTENSA_RTOS_H
#define XTENSA_RTOS_H
#ifdef __ASSEMBLER__
#include <xtensa/coreasm.h>
#else
#include <xtensa/config/core.h>
#endif
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
#include <xtensa/simcall.h>
/*
Include any RTOS specific definitions that are needed by this header.
*/
#include <FreeRTOSConfig.h>
/*
Convert FreeRTOSConfig definitions to XTENSA definitions.
However these can still be overridden from the command line.
*/
#ifndef XT_SIMULATOR
#if configXT_SIMULATOR
#define XT_SIMULATOR 1 /* Simulator mode */
#endif
#endif
#ifndef XT_BOARD
#if configXT_BOARD
#define XT_BOARD 1 /* Board mode */
#endif
#endif
#ifndef XT_TIMER_INDEX
#if defined configXT_TIMER_INDEX
#define XT_TIMER_INDEX configXT_TIMER_INDEX /* Index of hardware timer to be used */
#endif
#endif
#ifndef XT_INTEXC_HOOKS
#if configXT_INTEXC_HOOKS
#define XT_INTEXC_HOOKS 1 /* Enables exception hooks */
#endif
#endif
#if (!XT_SIMULATOR) && (!XT_BOARD)
#error Either XT_SIMULATOR or XT_BOARD must be defined.
#endif
/*
Name of RTOS (for messages).
*/
#define XT_RTOS_NAME FreeRTOS
/*
Check some Xtensa configuration requirements and report error if not met.
Error messages can be customize to the RTOS port.
*/
#if !XCHAL_HAVE_XEA2
#error "FreeRTOS/Xtensa requires XEA2 (exception architecture 2)."
#endif
/*******************************************************************************
RTOS CALLOUT MACROS MAPPED TO RTOS PORT-SPECIFIC FUNCTIONS.
Define callout macros used in generic Xtensa code to interact with the RTOS.
The macros are simply the function names for use in calls from assembler code.
Some of these functions may call back to generic functions in xtensa_context.h .
*******************************************************************************/
/*
Inform RTOS of entry into an interrupt handler that will affect it.
Allows RTOS to manage switch to any system stack and count nesting level.
Called after minimal context has been saved, with interrupts disabled.
RTOS port can call0 _xt_context_save to save the rest of the context.
May only be called from assembly code by the 'call0' instruction.
*/
// void XT_RTOS_INT_ENTER(void)
#define XT_RTOS_INT_ENTER _frxt_int_enter
/*
Inform RTOS of completion of an interrupt handler, and give control to
RTOS to perform thread/task scheduling, switch back from any system stack
and restore the context, and return to the exit dispatcher saved in the
stack frame at XT_STK_EXIT. RTOS port can call0 _xt_context_restore
to save the context saved in XT_RTOS_INT_ENTER via _xt_context_save,
leaving only a minimal part of the context to be restored by the exit
dispatcher. This function does not return to the place it was called from.
May only be called from assembly code by the 'call0' instruction.
*/
// void XT_RTOS_INT_EXIT(void)
#define XT_RTOS_INT_EXIT _frxt_int_exit
/*
Inform RTOS of the occurrence of a tick timer interrupt.
If RTOS has no tick timer, leave XT_RTOS_TIMER_INT undefined.
May be coded in or called from C or assembly, per ABI conventions.
RTOS may optionally define XT_TICK_PER_SEC in its own way (eg. macro).
*/
// void XT_RTOS_TIMER_INT(void)
#define XT_RTOS_TIMER_INT _frxt_timer_int
#define XT_TICK_PER_SEC configTICK_RATE_HZ
/*
Return in a15 the base address of the co-processor state save area for the
thread that triggered a co-processor exception, or 0 if no thread was running.
The state save area is structured as defined in xtensa_context.h and has size
XT_CP_SIZE. Co-processor instructions should only be used in thread code, never
in interrupt handlers or the RTOS kernel. May only be called from assembly code
and by the 'call0' instruction. A result of 0 indicates an unrecoverable error.
The implementation may use only a2-4, a15 (all other regs must be preserved).
*/
// void* XT_RTOS_CP_STATE(void)
#define XT_RTOS_CP_STATE _frxt_task_coproc_state
/*******************************************************************************
HOOKS TO DYNAMICALLY INSTALL INTERRUPT AND EXCEPTION HANDLERS PER LEVEL.
This Xtensa RTOS port provides hooks for dynamically installing exception
and interrupt handlers to facilitate automated testing where each test
case can install its own handler for user exceptions and each interrupt
priority (level). This consists of an array of function pointers indexed
by interrupt priority, with index 0 being the user exception handler hook.
Each entry in the array is initially 0, and may be replaced by a function
pointer of type XT_INTEXC_HOOK. A handler may be uninstalled by installing 0.
The handler for low and medium priority obeys ABI conventions so may be coded
in C. For the exception handler, the cause is the contents of the EXCCAUSE
reg, and the result is -1 if handled, else the cause (still needs handling).
For interrupt handlers, the cause is a mask of pending enabled interrupts at
that level, and the result is the same mask with the bits for the handled
interrupts cleared (those not cleared still need handling). This allows a test
case to either pre-handle or override the default handling for the exception
or interrupt level (see xtensa_vectors.S).
High priority handlers (including NMI) must be coded in assembly, are always
called by 'call0' regardless of ABI, must preserve all registers except a0,
and must not use or modify the interrupted stack. The hook argument 'cause'
is not passed and the result is ignored, so as not to burden the caller with
saving and restoring a2 (it assumes only one interrupt per level - see the
discussion in high priority interrupts in xtensa_vectors.S). The handler
therefore should be coded to prototype 'void h(void)' even though it plugs
into an array of handlers of prototype 'unsigned h(unsigned)'.
To enable interrupt/exception hooks, compile the RTOS with '-DXT_INTEXC_HOOKS'.
*******************************************************************************/
#define XT_INTEXC_HOOK_NUM (1 + XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI)
#ifndef __ASSEMBLER__
typedef unsigned (*XT_INTEXC_HOOK)(unsigned cause);
extern volatile XT_INTEXC_HOOK _xt_intexc_hooks[XT_INTEXC_HOOK_NUM];
#endif
/*******************************************************************************
CONVENIENCE INCLUSIONS.
Ensures RTOS specific files need only include this one Xtensa-generic header.
These headers are included last so they can use the RTOS definitions above.
*******************************************************************************/
#include "xtensa_context.h"
#ifdef XT_RTOS_TIMER_INT
#include "xtensa_timer.h"
#endif
/*******************************************************************************
Xtensa Port Version.
*******************************************************************************/
#define XTENSA_PORT_VERSION 1.6
#define XTENSA_PORT_VERSION_STRING "1.6"
#endif /* XTENSA_RTOS_H */

@ -0,0 +1,159 @@
/*******************************************************************************
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
XTENSA INFORMATION FOR RTOS TICK TIMER AND CLOCK FREQUENCY
This header contains definitions and macros for use primarily by Xtensa
RTOS assembly coded source files. It includes and uses the Xtensa hardware
abstraction layer (HAL) to deal with config specifics. It may also be
included in C source files.
User may edit to modify timer selection and to specify clock frequency and
tick duration to match timer interrupt to the real-time tick duration.
If the RTOS has no timer interrupt, then there is no tick timer and the
clock frequency is irrelevant, so all of these macros are left undefined
and the Xtensa core configuration need not have a timer.
*******************************************************************************/
#ifndef XTENSA_TIMER_H
#define XTENSA_TIMER_H
#ifdef __ASSEMBLER__
#include <xtensa/coreasm.h>
#endif
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
#include "xtensa_rtos.h" /* in case this wasn't included directly */
#include <FreeRTOSConfig.h>
/*
Select timer to use for periodic tick, and determine its interrupt number
and priority. User may specify a timer by defining XT_TIMER_INDEX with -D,
in which case its validity is checked (it must exist in this core and must
not be on a high priority interrupt - an error will be reported in invalid).
Otherwise select the first low or medium priority interrupt timer available.
*/
#if XCHAL_NUM_TIMERS == 0
#error "This Xtensa configuration is unsupported, it has no timers."
#else
#ifndef XT_TIMER_INDEX
#if XCHAL_TIMER3_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
#if XCHAL_INT_LEVEL(XCHAL_TIMER3_INTERRUPT) <= XCHAL_EXCM_LEVEL
#undef XT_TIMER_INDEX
#define XT_TIMER_INDEX 3
#endif
#endif
#if XCHAL_TIMER2_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
#if XCHAL_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL
#undef XT_TIMER_INDEX
#define XT_TIMER_INDEX 2
#endif
#endif
#if XCHAL_TIMER1_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
#if XCHAL_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL
#undef XT_TIMER_INDEX
#define XT_TIMER_INDEX 1
#endif
#endif
#if XCHAL_TIMER0_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
#if XCHAL_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL
#undef XT_TIMER_INDEX
#define XT_TIMER_INDEX 0
#endif
#endif
#endif
#ifndef XT_TIMER_INDEX
#error "There is no suitable timer in this Xtensa configuration."
#endif
#define XT_CCOMPARE (CCOMPARE + XT_TIMER_INDEX)
#define XT_TIMER_INTNUM XCHAL_TIMER_INTERRUPT(XT_TIMER_INDEX)
#define XT_TIMER_INTPRI XCHAL_INT_LEVEL(XT_TIMER_INTNUM)
#define XT_TIMER_INTEN (1 << XT_TIMER_INTNUM)
#if XT_TIMER_INTNUM == XTHAL_TIMER_UNCONFIGURED
#error "The timer selected by XT_TIMER_INDEX does not exist in this core."
#elif XT_TIMER_INTPRI > XCHAL_EXCM_LEVEL
#error "The timer interrupt cannot be high priority (use medium or low)."
#endif
#endif /* XCHAL_NUM_TIMERS */
/*
Set processor clock frequency, used to determine clock divisor for timer tick.
User should BE SURE TO ADJUST THIS for the Xtensa platform being used.
If using a supported board via the board-independent API defined in xtbsp.h,
this may be left undefined and frequency and tick divisor will be computed
and cached during run-time initialization.
NOTE ON SIMULATOR:
Under the Xtensa instruction set simulator, the frequency can only be estimated
because it depends on the speed of the host and the version of the simulator.
Also because it runs much slower than hardware, it is not possible to achieve
real-time performance for most applications under the simulator. A frequency
too low does not allow enough time between timer interrupts, starving threads.
To obtain a more convenient but non-real-time tick duration on the simulator,
compile with xt-xcc option "-DXT_SIMULATOR".
Adjust this frequency to taste (it's not real-time anyway!).
*/
#if defined(XT_SIMULATOR) && !defined(XT_CLOCK_FREQ)
#define XT_CLOCK_FREQ configCPU_CLOCK_HZ
#endif
#if !defined(XT_CLOCK_FREQ) && !defined(XT_BOARD)
#error "XT_CLOCK_FREQ must be defined for the target platform."
#endif
/*
Default number of timer "ticks" per second (default 100 for 10ms tick).
RTOS may define this in its own way (if applicable) in xtensa_rtos.h.
User may redefine this to an optimal value for the application, either by
editing this here or in xtensa_rtos.h, or compiling with xt-xcc option
"-DXT_TICK_PER_SEC=<value>" where <value> is a suitable number.
*/
#ifndef XT_TICK_PER_SEC
#define XT_TICK_PER_SEC configTICK_RATE_HZ /* 10 ms tick = 100 ticks per second */
#endif
/*
Derivation of clock divisor for timer tick and interrupt (one per tick).
*/
#ifdef XT_CLOCK_FREQ
#define XT_TICK_DIVISOR (XT_CLOCK_FREQ / XT_TICK_PER_SEC)
#endif
#ifndef __ASSEMBLER__
extern unsigned _xt_tick_divisor;
extern void _xt_tick_divisor_init(void);
#endif
#endif /* XTENSA_TIMER_H */

File diff suppressed because it is too large Load Diff

@ -224,7 +224,14 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
(that is, it will hold discrete messages with a little meta data that
says how big the next message is) check the buffer will be large enough
to hold at least one message. */
configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
if( xIsMessageBuffer == pdTRUE )
{
configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
}
else
{
configASSERT( xBufferSizeBytes > 0 );
}
configASSERT( xTriggerLevelBytes <= xBufferSizeBytes );
/* A trigger level of 0 would cause a waiting task to unblock even when

Loading…
Cancel
Save