Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FreeRTOS/FreeRTOS-Kernel-Partner-Supported-Ports.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShahzeb Ihsan <shahzeb@gmail.com>2024-01-10 07:51:33 +0300
committerGitHub <noreply@github.com>2024-01-10 07:51:33 +0300
commit72fadf4376a57a74602f3d6995342d489dce0df2 (patch)
tree7c5f005962d0317b1e3965c96c26677fd84312a2
parentda0185fbf1215706af66d020a67edf912193979a (diff)
Adding Infineon AURIX TC3xx portables for the Tasking compiler (#11)
* Adding Infineon AURIX TC3xx portables for the Tasking compiler * Add SPDX license identifier
-rw-r--r--Tasking/AURIX_TC3xx/port.c460
-rw-r--r--Tasking/AURIX_TC3xx/portmacro.h191
2 files changed, 651 insertions, 0 deletions
diff --git a/Tasking/AURIX_TC3xx/port.c b/Tasking/AURIX_TC3xx/port.c
new file mode 100644
index 0000000..1e29171
--- /dev/null
+++ b/Tasking/AURIX_TC3xx/port.c
@@ -0,0 +1,460 @@
+/*
+ * Copyright (c) 2023 Infineon Technologies AG. All rights reserved.
+ *
+ *
+ * IMPORTANT NOTICE
+ *
+ *
+ * Use of this file is subject to the terms of use agreed between (i) you or
+ * the company in which ordinary course of business you are acting and (ii)
+ * Infineon Technologies AG or its licensees. If and as long as no such
+ * terms of use are agreed, use of this file is subject to following:
+ *
+ * Boost Software License - Version 1.0 - August 17th, 2003
+ *
+ * Permission is hereby granted, free of charge, to any person or
+ * organization obtaining a copy of the software and accompanying
+ * documentation covered by this license (the "Software") to use, reproduce,
+ * display, distribute, execute, and transmit the Software, and to prepare
+ * derivative works of the Software, and to permit third-parties to whom the
+ * Software is furnished to do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer, must
+ * be included in all copies of the Software, in whole or in part, and all
+ * derivative works of the Software, unless such copies or derivative works are
+ * solely in the form of machine-executable object code generated by a source
+ * language processor.
+ *
+ * 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * SPDX-License-Identifier: BSL-1.0
+ */
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* Prgoram status word macros */
+#define portINITIAL_SYSTEM_PSW \
+ ( 0x000008FFUL ) /* Supervisor Mode, MPU Register Set 0 and Call Depth Counting disabled. */
+
+/* Context save area macros */
+#define portCSA_FCX_MASK ( 0x000FFFFFUL )
+#define portINITIAL_LOWER_PCXI ( 0x00300000UL ) /* Set UL to upper and PIE to 1 */
+#define portINITIAL_UPPER_PCXI ( 0x00200000UL ) /* Set UL to lower and PIE to 1 */
+#define portNUM_WORDS_IN_CSA ( 16 )
+
+extern volatile unsigned long * pxCurrentTCB;
+
+/* Tick and context switch config */
+#define portTICK_COUNT ( configSTM_CLOCK_HZ / configTICK_RATE_HZ )
+
+/* Register defines */
+static volatile uint32_t *const pxStm = configSTM;
+static volatile uint32_t *const pxStmSrc = configSTM_SRC;
+static volatile uint32_t *const pxContextSrc = configCONTEXT_SRC;
+#define portSTM_TIM0 0x10
+#define portSTM_CMP0 0x30
+#define portSTM_COMCON 0x38
+#define portSTM_ICR 0x3C
+#define portSTM_ISCR 0x40
+#define portSTM_OCS 0xE8
+
+#define portSTM_CMCON_MSTART0_OFF 8
+#define portSTM_CMCON_MSIZE0_OFF 0
+#define portSTM_ICR_CMP0EN_OFF 0
+#define portSTM_ICR_CMP0OS_OFF 2
+#define portSTM_ISCR_CMP0IRR_OFF 0
+
+static inline void vPortStartFirstTask( void );
+static inline void vPortInitContextSrc( void );
+static inline void vPortInitTickTimer( void );
+
+static inline void __attribute__( ( always_inline ) ) vPortLoadContext( unsigned char ucCallDepth );
+static inline void __attribute__( ( always_inline ) ) vPortSaveContext( unsigned char ucCallDepth );
+
+static inline uint32_t * __attribute__( ( always_inline ) ) pxPortCsaToAddress( uint32_t xCsa );
+
+static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
+
+/* FreeRTOS required functions */
+BaseType_t xPortStartScheduler( void )
+{
+ vPortInitTickTimer();
+ vPortInitContextSrc();
+ vPortStartFirstTask();
+
+ return 0;
+}
+
+void vPortEndScheduler()
+{
+ pxStmSrc[ 0 ] &= ~( 1 << portSRC_SRCR_SRE_OFF );
+ pxContextSrc[ 0 ] &= ~( 1 << portSRC_SRCR_SRE_OFF );
+}
+
+StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack,
+ TaskFunction_t pxCode,
+ void * pvParameters )
+{
+ uint32_t xLowerCsa = 0, xUpperCsa = 0;
+ uint32_t * pxUpperCSA = NULL;
+ uint32_t * pxLowerCSA = NULL;
+
+ /* Have to disable interrupts here because the CSAs are going to be
+ * manipulated. */
+ __disable();
+ {
+ /* DSync to ensure that buffering is not a problem. */
+ __dsync();
+
+ /* Consume two free CSAs. */
+ xLowerCsa = __mfcr( portCPU_FCX );
+ pxLowerCSA = pxPortCsaToAddress( xLowerCsa );
+
+ if( pxLowerCSA != NULL )
+ {
+ /* The Lower Links to the Upper. */
+ xUpperCsa = pxLowerCSA[ 0 ];
+ pxUpperCSA = pxPortCsaToAddress( pxLowerCSA[ 0 ] );
+ }
+
+ /* Check that we have successfully reserved two CSAs. */
+ if( ( pxLowerCSA != NULL ) && ( pxUpperCSA != NULL ) )
+ {
+ /* Remove the two consumed CSAs from the free CSA list. */
+ __mtcr( portCPU_FCX, pxUpperCSA[ 0 ] );
+ }
+ else
+ {
+ /* Simply trigger a context list depletion trap. */
+ __asm( "\tsvlcx" );
+ }
+ }
+ __enable();
+
+ /* Upper Context. */
+ memset( pxUpperCSA, 0, portNUM_WORDS_IN_CSA * sizeof( uint32_t ) );
+ pxUpperCSA[ 2 ] = ( uint32_t ) pxTopOfStack; /* A10; Stack Return aka Stack Pointer */
+ pxUpperCSA[ 1 ] = portINITIAL_SYSTEM_PSW; /* PSW */
+ pxUpperCSA[ 0 ] = portINITIAL_UPPER_PCXI;
+
+ /* Lower Context. */
+ memset( pxLowerCSA, 0, portNUM_WORDS_IN_CSA * sizeof( uint32_t ) );
+ pxLowerCSA[ 8 ] = ( uint32_t ) pvParameters; /* A4; Address Type Parameter Register */
+ pxLowerCSA[ 1 ] = ( uint32_t ) pxCode; /* A11; Return Address aka RA */
+ pxLowerCSA[ 0 ] = portINITIAL_LOWER_PCXI | xUpperCsa; /* PCXI pointing to the Upper context. */
+
+ /* Initialize the uxCriticalNesting. */
+ pxTopOfStack--;
+ *pxTopOfStack = 0;
+ /* Save the link to the CSA to the top of stack. */
+ pxTopOfStack--;
+ *pxTopOfStack = xLowerCsa;
+
+ return pxTopOfStack;
+}
+
+void __interrupt( configCONTEXT_INTERRUPT_PRIORITY ) __vector_table( configCPU_NR )
+vPortSystemContextHandler()
+{
+ /* Disable interrupts to protect section*/
+ __disable();
+
+ /* Do a save, switch, execute */
+ vPortSaveContext( 0 );
+ vTaskSwitchContext();
+ vPortLoadContext( 0 );
+
+ __enable();
+}
+
+void __interrupt( configTIMER_INTERRUPT_PRIORITY ) __vector_table( configCPU_NR )
+vPortSystemTickHandler()
+{
+ unsigned long ulSavedInterruptMask;
+ BaseType_t xYieldRequired;
+
+ /* Increment compare value by tick count */
+ pxStm[ portSTM_CMP0 >> 2 ] = pxStm[ portSTM_CMP0 >> 2 ] + portTICK_COUNT;
+ pxStm[ portSTM_ISCR >> 2 ] |= ( 1 << portSTM_ISCR_CMP0IRR_OFF );
+
+ /* Check for possible tick drop.
+ * If the time is beyond the compare value, the next tick will need a complete
+ * wrap around. The tick count isn't accruate any more. Increase the tick count
+ * or adapt to execute xTaskIncrementTick multiple times depending on the
+ * counts missed. */
+ #if configCPU_STM_DEBUG != 0
+ configASSERT( ( pxStm[ portSTM_CMP0 >> 2 ] - pxStm[ portSTM_TIM0 >> 2 ] ) <= portTICK_COUNT );
+ #endif
+
+ /* Kernel API calls require Critical Sections. */
+ ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
+ {
+ /* Increment the Tick. */
+ xYieldRequired = xTaskIncrementTick();
+ }
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
+
+ portYIELD_FROM_ISR( xYieldRequired );
+}
+
+void __attribute__( ( noinline ) ) vPortSyscallYield( void );
+
+int
+#if configPROVIDE_SYSCALL_TRAP != 0
+ __trap( configTIMER_INTERRUPT_PRIORITY ) __vector_table( configCPU_NR )
+#endif
+vPortSyscallHandler( unsigned char id )
+{
+ switch( id )
+ {
+ case 0:
+ vPortSyscallYield();
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+void vPortInitTickTimer()
+{
+ pxStm[ portSTM_COMCON >> 2 ] =
+ ( 0 << portSTM_CMCON_MSTART0_OFF ) | ( 31 << portSTM_CMCON_MSIZE0_OFF );
+ pxStm[ portSTM_ICR >> 2 ] &= ~( 1 << portSTM_ICR_CMP0OS_OFF );
+ pxStmSrc[ 0 ] = ( ( configCPU_NR > 0 ?
+ configCPU_NR + 1 : configCPU_NR ) << portSRC_SRCR_TOS_OFF ) |
+ ( ( configTIMER_INTERRUPT_PRIORITY ) << portSRC_SRCR_SRPN_OFF );
+ pxStmSrc[ 0 ] |= ( 1 << portSRC_SRCR_SRE_OFF );
+ pxStm[ portSTM_CMP0 >> 2 ] = pxStm[ portSTM_TIM0 >> 2 ];
+ pxStm[ portSTM_ISCR >> 2 ] |= ( 1 << portSTM_ISCR_CMP0IRR_OFF );
+ pxStm[ portSTM_ICR >> 2 ] |= ( 1 << portSTM_ICR_CMP0EN_OFF );
+ pxStm[ portSTM_CMP0 >> 2 ] = pxStm[ portSTM_TIM0 >> 2 ] + portTICK_COUNT;
+ #if configTICK_STM_DEBUG != 0
+ pxStm[ portSTM_OCS >> 2 ] = 0x12000000;
+ #endif
+}
+
+void vPortInitContextSrc()
+{
+ pxContextSrc[ 0 ] =
+ ( ( configCPU_NR > 0 ?
+ configCPU_NR + 1 : configCPU_NR ) << portSRC_SRCR_TOS_OFF ) |
+ ( ( configCONTEXT_INTERRUPT_PRIORITY ) << portSRC_SRCR_SRPN_OFF );
+ pxContextSrc[ 0 ] |= ( 1 << portSRC_SRCR_SRE_OFF );
+}
+
+void vPortStartFirstTask()
+{
+ /* Disable interrupts */
+ __disable();
+
+ vPortLoadContext( 0 );
+
+ /* Reset the call stack counting, to avoid trap on rfe */
+ unsigned long ulPsw = __mfcr( portCPU_PSW );
+
+ ulPsw &= ~( portCPU_PSW_CSC_MSK );
+ __mtcr( portCPU_PSW, ulPsw );
+
+ /* Load the lower context and upper context through rfe to enable irqs */
+ __asm( "\trslcx" );
+ __asm( "\trfe" );
+ __nop();
+ __nop();
+ __nop();
+}
+
+void vPortLoadContext( unsigned char ucCallDepth )
+{
+ uint32_t ** ppxTopOfStack;
+ uint32_t uxLowerCSA;
+
+ /* Dsync is required to complete any memory requests */
+ __dsync();
+
+ /* Load the new CSA id from the stack and update the stack pointer */
+ ppxTopOfStack = ( uint32_t ** ) pxCurrentTCB;
+ uxLowerCSA = **ppxTopOfStack;
+ ( *ppxTopOfStack )++;
+ uxCriticalNesting = **ppxTopOfStack;
+ ( *ppxTopOfStack )++;
+
+ /* Store the lower context directly if inside the syscall or interrupt,
+ * else replace the lower context in the call stack. */
+ if( !ucCallDepth )
+ {
+ /* Update the link register */
+ __mtcr( portCPU_PCXI, uxLowerCSA );
+ }
+ else
+ {
+ /* Update previous lower context */
+ uint32_t * pxCSA = pxPortCsaToAddress( __mfcr( portCPU_PCXI ) );
+ int i;
+
+ for(i = 0; i < ucCallDepth - 1; i++)
+ {
+ pxCSA = pxPortCsaToAddress( pxCSA[ 0 ] );
+ }
+
+ pxCSA[ 0 ] = uxLowerCSA;
+ }
+}
+
+void vPortSaveContext( unsigned char ucCallDepth )
+{
+ uint32_t ** ppxTopOfStack;
+ uint32_t * pxLowerCSA, * pxUpperCSA;
+ uint32_t uxLowerCSA;
+
+ /* Dsync is required for save CSA access */
+ __dsync();
+
+ /* Get the current context information. */
+ uxLowerCSA = __mfcr( portCPU_PCXI );
+
+ /* If this function is used inside a function from the syscall or interrupt,
+ * load the correct context from the call stack */
+ if( ucCallDepth )
+ {
+ uint32_t * pxCSA = pxPortCsaToAddress( uxLowerCSA );
+ int i;
+
+ for(i = 0; i < ucCallDepth - 1; i++)
+ {
+ pxCSA = pxPortCsaToAddress( pxCSA[ 0 ] );
+ }
+
+ uxLowerCSA = pxCSA[ 0 ];
+ }
+
+ pxLowerCSA = pxPortCsaToAddress( uxLowerCSA );
+ pxUpperCSA = pxPortCsaToAddress( pxLowerCSA[ 0 ] );
+
+ /* Load the stack pointer */
+ ppxTopOfStack = ( uint32_t ** ) pxCurrentTCB;
+ /* Update the stack info in the TCB */
+ *ppxTopOfStack = ( uint32_t * ) pxUpperCSA[ 2 ];
+ /* Place ucNestedContext */
+ ( *ppxTopOfStack )--;
+ **ppxTopOfStack = uxCriticalNesting;
+ /* Place the lower CSA id on the stack */
+ ( *ppxTopOfStack )--;
+ **ppxTopOfStack = uxLowerCSA;
+}
+
+void vPortSyscallYield()
+{
+ /* Do a save, switch, execute */
+ vPortSaveContext( configSYSCALL_CALL_DEPTH );
+ vTaskSwitchContext();
+ vPortLoadContext( configSYSCALL_CALL_DEPTH );
+}
+
+uint32_t * pxPortCsaToAddress( uint32_t xCsa )
+{
+ uint32_t pxCsa;
+
+ pxCsa = ( __extru( xCsa, 16, 4 ) << 28 );
+ pxCsa = __insert( pxCsa, xCsa, 6, 16 );
+ return ( uint32_t * ) pxCsa;
+}
+
+void vPortEnterCritical( void )
+{
+ portDISABLE_INTERRUPTS();
+ uxCriticalNesting++;
+
+ /* This is not the interrupt safe version of the enter critical function so
+ * assert() if it is being called from an interrupt context. Only API
+ * functions that end in "FromISR" can be used in an interrupt. Only assert if
+ * the critical nesting count is 1 to protect against recursive calls if the
+ * assert function also uses a critical section. */
+ if( uxCriticalNesting == 1 )
+ {
+ portASSERT_IF_IN_ISR();
+ }
+}
+
+void vPortExitCritical( void )
+{
+ configASSERT( uxCriticalNesting );
+ uxCriticalNesting--;
+
+ if( uxCriticalNesting == 0 )
+ {
+ portENABLE_INTERRUPTS();
+ }
+}
+
+/*
+ * When a task is deleted, it is yielded permanently until the IDLE task
+ * has an opportunity to reclaim the memory that that task was using.
+ * Typically, the memory used by a task is the TCB and Stack but in the
+ * TriCore this includes the CSAs that were consumed as part of the Call
+ * Stack. These CSAs can only be returned to the Globally Free Pool when
+ * they are not part of the current Call Stack, hence, delaying the
+ * reclamation until the IDLE task is freeing the task's other resources.
+ * This function uses the head of the linked list of CSAs (from when the
+ * task yielded for the last time) and finds the tail (the very bottom of
+ * the call stack) and inserts this list at the head of the Free list,
+ * attaching the existing Free List to the tail of the reclaimed call stack.
+ *
+ * NOTE: In highly loaded systems the release of used CSAs might be delayed,
+ * since it is executed es part of the calling tasks, if the deleted task is
+ * different from the calling tasks, or as part of the idle task, if the deleted
+ * tasks is the same as the calling task.
+ */
+void vPortReclaimCSA( unsigned long ** pxTCB )
+{
+ uint32_t ulHeadCSA, ulFreeCSA;
+ uint32_t * pulNextCSA;
+
+ /* The lower context (PCXI value) to return to the task is stored as the
+ * current element on the stack. Mask off everything in the PCXI register
+ * other than the address. */
+ ulHeadCSA = ( **pxTCB ) & portCSA_FCX_MASK;
+
+ /* Iterate over the CSAs that were consumed as part of the task. */
+ for(pulNextCSA = pxPortCsaToAddress( ulHeadCSA );
+ ( pulNextCSA[ 0 ] & portCSA_FCX_MASK ) != 0;
+ pulNextCSA = pxPortCsaToAddress( pulNextCSA[ 0 ] ) )
+ {
+ /* Mask off everything in the PCXI value other than the address. */
+ pulNextCSA[ 0 ] &= portCSA_FCX_MASK;
+ }
+
+ __disable();
+ {
+ /* Look up the current free CSA head. */
+ __dsync();
+ ulFreeCSA = __mfcr( portCPU_FCX );
+
+ /* Join the current free onto the tail of what is being reclaimed. */
+ pulNextCSA[ 0 ] = ulFreeCSA;
+
+ /* Move the head of the reclaimed into the Free. */
+ __mtcr( portCPU_FCX, ulHeadCSA );
+ }
+ __enable();
+}
+
+void __attribute__( ( noreturn ) ) vPortLoopForever( void )
+{
+ while( 1 )
+ {
+ }
+}
diff --git a/Tasking/AURIX_TC3xx/portmacro.h b/Tasking/AURIX_TC3xx/portmacro.h
new file mode 100644
index 0000000..bfebd67
--- /dev/null
+++ b/Tasking/AURIX_TC3xx/portmacro.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2023 Infineon Technologies AG. All rights reserved.
+ *
+ *
+ * IMPORTANT NOTICE
+ *
+ *
+ * Use of this file is subject to the terms of use agreed between (i) you or
+ * the company in which ordinary course of business you are acting and (ii)
+ * Infineon Technologies AG or its licensees. If and as long as no such
+ * terms of use are agreed, use of this file is subject to following:
+ *
+ * Boost Software License - Version 1.0 - August 17th, 2003
+ *
+ * Permission is hereby granted, free of charge, to any person or
+ * organization obtaining a copy of the software and accompanying
+ * documentation covered by this license (the "Software") to use, reproduce,
+ * display, distribute, execute, and transmit the Software, and to prepare
+ * derivative works of the Software, and to permit third-parties to whom the
+ * Software is furnished to do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer, must
+ * be included in all copies of the Software, in whole or in part, and all
+ * derivative works of the Software, unless such copies or derivative works are
+ * solely in the form of machine-executable object code generated by a source
+ * language processor.
+ *
+ * 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * SPDX-License-Identifier: BSL-1.0
+ */
+
+#ifndef PORTMACRO_H
+#define PORTMACRO_H
+
+#ifdef __cplusplus
+ extern "C"
+#endif
+
+#include "FreeRTOSConfig.h"
+
+#define portCPU_PSW 0xFE04
+#define portCPU_PSW_IS_OFF ( 9 )
+#define portCPU_PSW_CSC_MSK ( 0x7F )
+#define portCPU_ICR 0xFE2C
+#define portCPU_ICR_CCPN_OFF ( 0 )
+#define portCPU_ICR_CCPN_MSK ( 0x000000FFUL )
+#define portCPU_FCX 0xFE38
+#define portCPU_PCXI 0xFE00
+#define portCPU_CORE_ID 0xFE1C
+
+/* Register defintions */
+#define portSRC_SRCR_SRPN_OFF 0
+#define portSRC_SRCR_SRE_OFF 10
+#define portSRC_SRCR_TOS_OFF 11
+#define portSRC_SRCR_SRR_OFF 24
+#define portSRC_SRCR_SETR_OFF 26
+
+/* Type definitions. */
+#define portCHAR char
+#define portSHORT short
+#define portLONG long
+#define portFLOAT float
+#define portDOUBLE double
+#define portSTACK_TYPE uint32_t
+#define portBASE_TYPE long
+#define portPOINTER_SIZE_TYPE uintptr_t
+
+typedef portSTACK_TYPE StackType_t;
+typedef long BaseType_t;
+typedef unsigned long UBaseType_t;
+
+#if ( configUSE_16_BIT_TICKS == 1 )
+ typedef unsigned short TickType_t;
+ #define portMAX_DELAY ( TickType_t ) 0xffff
+#else
+ typedef unsigned int TickType_t;
+ #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
+#endif
+
+/* FreeRTOS parameters */
+#define portTICK_TYPE_IS_ATOMIC 1
+#define portSTACK_GROWTH ( -1 )
+#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
+#define portBYTE_ALIGNMENT 8
+#define portCRITICAL_NESTING_IN_TCB 0
+
+/* Attributes */
+#define portDONT_DISCARD __attribute__( ( used ) )
+#define portNORETURN __attribute__( ( noreturn ) )
+
+/* Instructions */
+#define portNOP() __nop()
+#define portMEMORY_BARRIER() __dsync()
+
+/* Critical section management */
+extern void vPortEnterCritical( void );
+extern void vPortExitCritical( void );
+#define portENTER_CRITICAL() vPortEnterCritical()
+#define portEXIT_CRITICAL() vPortExitCritical()
+#define portENABLE_INTERRUPTS() vPortSetCCPN( 0 );
+#define portDISABLE_INTERRUPTS() vPortSetCCPN( configMAX_API_CALL_INTERRUPT_PRIORITY )
+#define portASSERT_IF_IN_ISR() configASSERT( ( __mfcr( portCPU_PSW ) & ( 1 << portCPU_PSW_IS_OFF ) ) == 0 )
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedMaskValue ) vPortSetICR( ulSavedMaskValue )
+#define portSET_INTERRUPT_MASK_FROM_ISR() xPortSetCCPN( configMAX_API_CALL_INTERRUPT_PRIORITY )
+
+
+#ifndef configYIELD_SYSCALL_ID
+ #define configYIELD_SYSCALL_ID 0
+#endif
+
+#define portYIELD() __syscall( configYIELD_SYSCALL_ID )
+#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) \
+ { \
+ const uint32_t xTrigger = ( ( *configCONTEXT_SRC >> portSRC_SRCR_SRR_OFF ) & 0x1 ) != 1 && ( xHigherPriorityTaskWoken != 0 ); \
+ *configCONTEXT_SRC |= ( xTrigger << portSRC_SRCR_SETR_OFF ); \
+ \
+ /* Wait until write request completes to trigger IRQ */ \
+ __dsync(); \
+ __isync(); \
+ }
+
+
+#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
+ #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
+#endif
+
+#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
+
+/* Check the configuration. */
+ #if ( configMAX_PRIORITIES > 32 )
+ #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
+ #endif
+
+/* Store/clear the ready priorities in a bit map. */
+ #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
+ #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
+
+ #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( ( uint32_t ) __clz( ( uxReadyPriorities ) ) ) )
+
+#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
+
+/* Function prototypes */
+#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
+#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
+
+/* TCB handling */
+extern void vPortReclaimCSA( unsigned long ** pxTCB );
+#define portCLEAN_UP_TCB( pxTCB ) vPortReclaimCSA( ( unsigned long ** ) ( pxTCB ) )
+
+
+/* ICR & CCPN modifying functions to enable and disable interrupts.
+ * Only interrupts with a priority lower than
+ */
+static void __attribute__( ( used, always_inline ) ) vPortSetCCPN( unsigned char ucCCPN )
+{
+ __disable();
+ __mtcr( portCPU_ICR, ( __mfcr( portCPU_ICR ) & ~portCPU_ICR_CCPN_MSK ) | ( ucCCPN & portCPU_ICR_CCPN_MSK ) );
+ __enable();
+}
+
+static void __attribute__( ( used, always_inline ) ) vPortSetICR( portBASE_TYPE ulICR )
+{
+ __disable();
+ __mtcr( portCPU_ICR, ( unsigned int ) ulICR );
+ __enable();
+}
+
+static portBASE_TYPE __attribute__( ( used, always_inline ) ) xPortSetCCPN( unsigned char ucCCPN )
+{
+ uint32_t xICR;
+
+ __disable();
+ xICR = __mfcr( portCPU_ICR );
+ __mtcr( portCPU_ICR, ( xICR & ~portCPU_ICR_CCPN_MSK ) | ( ucCCPN & portCPU_ICR_CCPN_MSK ) );
+ __enable();
+ return ( portBASE_TYPE ) xICR;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PORTMACRO_H */