Supported new feature Interrupt Stack Management for U2x Port. (#28)
* Add new port layer for CCRH U2x and GHS U2x
* Updated U2x port to support U2Cx devices.
* Due to internal constraint, we need to postpone the upstream. We will resume once it will be ready.
* Update RH850 U2x resource references.
* Due to internal constraint, we need to postpone the upstream. We will resume once it will be ready.
* Update RH850 U2x resource references.
* Updated U2x port to support U2Cx devices.
* Due to internal constraint, we need to postpone the upstream. We will resume once it will be ready.
* Update RH850 U2x resource references
* Update RH850 U2x resource references
* updated U2x FreeRTOS port to support Stack Interrupt Management.
* updated U2x FreeRTOS port to support Stack Interrupt Management.
* 1. Supported new feature Interrupt Stack Management.
2. Improved the usage of FXU/FPU.
3. Improved the content in README.md.
---------
Co-authored-by: Duc Dat Le <duc.le.xm@renesas.com>
Co-authored-by: vung.tran.zg <vung.tran.zg@renesas.com>
diff --git a/CCRH/Image/Allocate_Stack_For_Vector_Table.png b/CCRH/Image/Allocate_Stack_For_Vector_Table.png
new file mode 100644
index 0000000..1c2446c
--- /dev/null
+++ b/CCRH/Image/Allocate_Stack_For_Vector_Table.png
Binary files differ
diff --git a/CCRH/Image/Assembler.png b/CCRH/Image/Assembler.png
new file mode 100644
index 0000000..264ecc2
--- /dev/null
+++ b/CCRH/Image/Assembler.png
Binary files differ
diff --git a/CCRH/U2x/README.md b/CCRH/U2x/README.md
index 81ea1b8..4dbb7b6 100644
--- a/CCRH/U2x/README.md
+++ b/CCRH/U2x/README.md
@@ -18,26 +18,120 @@
## Link to Test Project
-The test project can be found in [RH850_U2Ax_CCRH](https://github.com/FreeRTOS/FreeRTOS-Partner-Supported-Demos/tree/main/RH850_U2Ax_CCRH) and [RH850_U2Bx_CCRH](https://github.com/FreeRTOS/FreeRTOS-Partner-Supported-Demos/tree/main/RH850_U2Bx_CCRH). These projects contain example tasks and configurations to help you get started with FreeRTOS on the RH850/U2Ax and U2Bx.
+The test project can be found in [RH850_U2Ax_CCRH](https://github.com/FreeRTOS/FreeRTOS-Partner-Supported-Demos/tree/main/RH850_U2Ax_CCRH) and [RH850_U2Bx_CCRH](https://github.com/FreeRTOS/FreeRTOS-Partner-Supported-Demos/tree/main/RH850_U2Bx_CCRH). These projects contain example tasks and configurations to help you get started with FreeRTOS on the RH850/U2Ax and RH850/U2Bx.
+
+## Setup for Vector Table
+ 1. Allocate the Stack area in Linker Script:<br />
+ - In the Linker configuration, create a dedicated Stack (memory region) for the Vector Table of each Processing Element (PE).
+
+ For example, in **Section Settings**, add:<br />
+ | Address | Section |
+ |------------|---------------------|
+ | 0x00040000 | .inttable_PE0.const |
+ | 0x00041000 | .inttable_PE1.const |
+ | 0x00042000 | .inttable_PE2.const |
+
+ 
+
+ 2. Declare the Vector Table in the source code:<br />
+ - In the application source code, define the Vector Table.<br />
+ - Map this Vector Table to the Stack region that was created in the Linker Script.
+
+ For example, in **main.c** file, add:<br />
+ <pre>
+ /***********************************************************************************************************************
+ * Vector Table Configuration
+ **********************************************************************************************************************/
+ /* Interrupt vector table for PE0. Mapping into the memory section ".inttable_PE0". */
+ #pragma section const ".inttable_PE0"
+ const int_vector_t g_vector_table_PE0[ RTOS_VECTOR_TABLE_MAX_ENTRIES ] =
+ {
+ #if ( configNUMBER_OF_CORES > 1 )
+ [ 1 ] = vPortIPIHander, /* Internal processor interrupt 1 */
+ #endif /* End of #if (configNUMBER_OF_CORES > 1) */
+
+ [ 360 ] = vPortTickISR, /* INTOSTM0TINT (OSTM0 interrupt) */
+ [ 621 ] = r_Config_UART0_interrupt_send, /* EIC621: INTRLIN30UR0 (RLIN30 transmit interrupt) */
+ };
+
+ #if ( configNUMBER_OF_CORES > 1 )
+ /* Interrupt vector table for PE1. Mapping into the memory section ".inttable_PE1". */
+ #pragma section const ".inttable_PE1"
+ const int_vector_t g_vector_table_PE1[ RTOS_VECTOR_TABLE_MAX_ENTRIES ] =
+ {
+ [ 1 ] = vPortIPIHander, /* Internal processor interrupt 1 */
+ };
+
+ /* Interrupt vector table for PE2. Mapping into the memory section ".inttable_PE2". */
+ #pragma section const ".inttable_PE2"
+ const int_vector_t g_vector_table_PE2[ RTOS_VECTOR_TABLE_MAX_ENTRIES ] =
+ {
+ [ 1 ] = vPortIPIHander, /* Internal processor interrupt 1 */
+ };
+ #endif /* End of #if (configNUMBER_OF_CORES > 1) */
+
+ #pragma section default
+ </pre>
+
+ 3. Assign the Vector Table into the INTBP register in Startup:<br />
+ - In System Startup, assign the Vector Table address into the INTBP register so that the Processor knows where to fetch Interrupt Vectors.
+
+ For example, in **Startup** file, add:<br />
+ <pre>
+ $ifdef PE1_USED
+ __PE1:
+ ; Initialization of the interrupt base pointer.
+ .extern _g_vector_table_PE1
+ mov #_g_vector_table_PE1, r10
+ ldsr r10, 4, 1 ; INTBP
+
+ mov #_PE1_stacktop, sp ; Set sp register.
+ mov #__sex_entry_PE1, r10 ; First set EBASE register address.
+ jr32 __DONE
+ $endif
+
+ $ifdef PE2_USED
+ __PE2:
+ ; Initialization of the interrupt base pointer.
+ .extern _g_vector_table_PE2
+ mov #_g_vector_table_PE2, r10
+ ldsr r10, 4, 1 ; INTBP
+
+ mov #_PE2_stacktop, sp ; Set sp register.
+ mov #__sex_entry_PE2, r10 ; First set EBASE register address.
+ jr32 __DONE
+ $endif
+ </pre>
+
+ 4. Interrupt Vector Configuration:<br />
+ - Interrupt handling must be configured using the Direct Vector method, e.g. by configuring EBASE or EICn registers.
+
+## FPU and FXU Units Usage
+ - The `FXU Unit` is available only on RH850 U2Bx devices.<br />
+ To ensure correct operation, any task requiring FXU must run on an FXU-enabled core. In SMP systems, the core assignment shall be fixed using CPU affinity via the `vTaskCoreAffinitySet()` function.
+
+ - By default, the FPU and FXU operations are enabled, which may introduce redundant code and impact performance.<br />
+ If they are not required by the application, FPU and FXU related code can be disabled by defining the macros `configDISABLE_FPU` and `configDISABLE_FXU` respectively.<br />
+ Additionally, `-DconfigDISABLE_FPU` and `-DconfigDISABLE_FXU` should be added to the compiler option.
+
+ For example, in **Property** of CC-RH (Build Tool):<br />
+ 
## Note
- 1. The minimal stack size (configMINIMAL_STACK_SIZE) must be included the reserved memory for nested interrupt. This formula can be referred: `(task_context_size) * (2 + configMAX_INT_NESTING) + Stack_depth_of_taskcode`
- In which, `task_context_size` is calculated as `36*4bytes = 144bytes` (when FPU enabled) or `34*4bytes = 136` (when FPU disabled), configMAX_INT_NESTING is `02` as default (Note that a value of `0` is not allowed).
+ 1. Refer this formula to estimate the minimal stack size (configMINIMAL_STACK_SIZE) used: `[(task_context_size) * 2] + stack_required_for_taskcode`.<br />
+ In which, `task_context_size` is calculated as `36 * 4 bytes = 144 bytes`.
+
2. Users need to create a memory section named `mev_address` in `CRAM` for Exclusive Control functionality. Users should initialize the `mev_address` section in the startup file.
-Example:
- ```
- ; .mev_address section in CRAM is used for Sync flags
- mov #__s.mev_address.bss, r20
- st.w r0, 0[r20]
- ```
- 3. The `FXU unit` is only available on `core 0`. Users must ensure that FXU operations are restricted to `core 0` by using the `vTaskCoreAffinitySet` function provided by FreeRTOS SMP.
- 4. FXU can be enabled by specific compiler option `-DconfigENABLE_FXU`. FPU can be enabled by specific compiler option `-DconfigENABLE_FPU`
- 5. The macros `configENABLE_FXU` and `configENABLE_FPU` must be defined in `FreeRTOSConfig.h`.
- 6. This port supports U2Ax and U2Bx devices. The user must configure `configDEVICE_NAME` with the value `U2Bx_DEVICES` or `U2Ax_DEVICES` to specify which device is being used.
- 7. The User can configure the interrupt priority of the OSTM Timer using `configTIMER_INT_PRIORITY`, with 16 levels available (0 being the highest priority and 15 the lowest).
- 8. This port also supports the configuration of contiguous CPU cores in FreeRTOS, allowing the user to set task affinity for execution on specific cores or subsets of cores.
+ For example:<br />
+ <pre>
+ ; .mev_address section in CRAM is used for Sync flags
+ mov #__s.mev_address.bss, r20
+ st.w r0, 0[r20]</pre>
+ 3. This port supports both U2Ax and U2Bx devices. The User must configure `configDEVICE_NAME` with the value `U2Bx_DEVICES` or `U2Ax_DEVICES` to specify which device is being used.
+
+ 4. This port also supports the configuration of contiguous CPU cores in FreeRTOS SMP, allowing the User to set task affinity for execution on specific cores or subsets of cores.
## Other Relevant Information
@@ -52,4 +146,4 @@
- If you encounter any issues or have questions about this port, please open an issue in this repository or contact the maintainer.
- **Contributing:**
- - Contributions to improve this port are welcome. Please fork the repository, make your changes, and submit a pull request.
\ No newline at end of file
+ - Contributions to improve this port are welcome. Please fork the repository, make your changes, and submit a pull request.
diff --git a/CCRH/U2x/port.c b/CCRH/U2x/port.c
index 8c44273..7f326e3 100644
--- a/CCRH/U2x/port.c
+++ b/CCRH/U2x/port.c
@@ -46,7 +46,7 @@
#define portFXSR_REGISTER_SEL ( 10 )
/* PSW.EBV and PSW.CUx bits are kept as current status */
-#define portINITIAL_PSW_MASK ( 0x00078000 )
+#define portINITIAL_PSW_MASK ( 0x00038000 )
#define portCURRENT_PSW_VALUE ( portSTSR( portPSW_REGISTER_ID, portREGISTER_SEL_0 ) )
#define portCURRENT_SR_ZERO_VALUE ( ( StackType_t ) 0x00000000 )
#define portCURRENT_FPSR_VALUE ( portSTSR( portFPSR_REGISTER_ID, portREGISTER_SEL_0 ) )
@@ -141,8 +141,8 @@
/* Macros indicatings status of scheduler request */
#define PORT_SCHEDULER_NOREQUEST 0UL
-#define PORT_SCHEDULER_TASKSWITCH 1UL /* Do not modify */
-#define PORT_SCHEDULER_STARTFIRSTTASK 2UL /* Do not modify */
+#define PORT_SCHEDULER_TASKSWITCH 1UL /* Do not modify */
+#define PORT_SCHEDULER_STARTFIRSTTASK 2UL /* Do not modify */
#ifndef configSETUP_TICK_INTERRUPT
@@ -151,19 +151,6 @@
#define configSETUP_TICK_INTERRUPT() prvSetupTimerInterrupt()
#endif /* configSETUP_TICK_INTERRUPT */
-#if ( !defined( configMAX_INT_NESTING ) || ( configMAX_INT_NESTING == 0 ) )
-
-/* Set the default value for depth of nested interrupt. In theory, the
- * microcontroller have mechanism to limit number of nested level of interrupt
- * by priority (maximum 16 levels). However, the large stack memory should be
- * prepared for each task to save resource in interrupt handler. Therefore, it
- * is necessary to limit depth of nesting interrupt to optimize memory usage.
- * In addition, the execution time of interrupt handler should be very short
- * (typically not exceed 20us), this constraint does not impact to system.
- */
- #define configMAX_INT_NESTING 2UL
-#endif
-
/*
* Used to catch tasks that attempt to return from their implementing function.
*/
@@ -191,7 +178,11 @@
* It is necessary to control maximum stack depth.
*/
volatile UBaseType_t uxInterruptNesting[ configNUMBER_OF_CORES ] = { 0 };
-volatile const UBaseType_t uxPortMaxInterruptDepth = configMAX_INT_NESTING;
+
+#ifndef configPORT_ISR_STACK_TOPS
+ #error "Define configPORT_ISR_STACK_TOPS in FreeRTOSConfig.h"
+#endif
+const UBaseType_t uxInterruptStack[ configNUMBER_OF_CORES ] = configPORT_ISR_STACK_TOPS;
/* Count number of nested locks by same cores. The lock is completely released
* only if this count is decreased to 0, the lock is separated for task and isr */
@@ -224,8 +215,10 @@
* cores. The core will wait until lock will be available, whilst the core which
* already had lock can acquire lock without waiting. This function could be
* call from task and interrupt context, the critical section is called as in ISR */
- void vPortRecursiveLockAcquire( BaseType_t xCoreID, BaseType_t xFromIsr );
- void vPortRecursiveLockRelease( BaseType_t xCoreID, BaseType_t xFromIsr );
+ void vPortRecursiveLockAcquire( BaseType_t xCoreID,
+ BaseType_t xFromIsr );
+ void vPortRecursiveLockRelease( BaseType_t xCoreID,
+ BaseType_t xFromIsr );
#endif /* (configNUMBER_OF_CORES > 1) */
@@ -269,7 +262,7 @@
BaseType_t xPortGET_CORE_ID( void )
{
#if ( configNUMBER_OF_CORES > 1 )
- return( portSTSR( 0, 2 ) ); /* Get PEID value */
+ return portSTSR( 0, 2 ); /* Get PEID value */
#else
/* In single core, xPortGET_CORE_ID is used in this port only. The dummy
@@ -381,46 +374,32 @@
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R30; /* R30 (EP) */
pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R1; /* R1 */
+ *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R1; /* R1 */
pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R2; /* R2 */
+ *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R2; /* R2 */
pxTopOfStack--;
+ /* if FPU is enabled, initialize the FPU registers in Stack */
+ #ifndef configDISABLE_FPU
+ {
+ *pxTopOfStack = ( StackType_t ) ( portCURRENT_FPSR_VALUE & portINITIAL_FPSR_MASK ); /* FPSR */
+ pxTopOfStack--;
+ *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* FPEPC */
+ pxTopOfStack--;
+ }
+ #endif /* End of #ifndef configDISABLE_FPU */
+
/* Keep System pre-configuration (HV, CUx, EBV) as current setting in PSW register */
*pxTopOfStack = ( StackType_t ) ( portCURRENT_PSW_VALUE & portINITIAL_PSW_MASK ); /* EIPSW */
pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) pxCode; /* EIPC */
+ *pxTopOfStack = ( StackType_t ) pxCode; /* EIPC */
pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* EIIC */
+ *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* EIIC */
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) ( portCURRENT_PSW_VALUE & portINITIAL_PSW_MASK ); /* CTPSW */
pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* CTPC */
-
- /* if FPU is enabled, initialize the FPU registers in Stack */
- #if ( configENABLE_FPU == 1 )
- pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) ( portCURRENT_FPSR_VALUE & portINITIAL_FPSR_MASK ); /* FPSR */
- pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* FPEPC */
- #endif /* (configENABLE_FPU == 1) */
-
- /* if FXU is enabled, initialize the FXU registers in Stack */
- #if ( configENABLE_FXU == 1 )
- /* FXU Unit is available in PE0 only */
- if( 0 == xPortGET_CORE_ID() )
- {
- pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) ( portCURRENT_FXSR_VALUE & portINITIAL_FXSR_MASK ); /* FXSR */
- pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* FXXP */
- }
- else
- {
- /* Do nothing */
- }
- #endif /* (configENABLE_FXU == 1) */
+ *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* CTPC */
return pxTopOfStack;
}
@@ -494,9 +473,7 @@
* should instead call vTaskDelete( NULL ).
*
* Artificially force an assert() to be triggered if configASSERT() is
- * defined, then stop here so application writers can catch the error. */
-
- /* This statement will always fail, triggering the assert */
+ * defined, then stop here so application writers can catch the error. *//* This statement will always fail, triggering the assert */
configASSERT( pdFALSE );
/*
@@ -621,11 +598,12 @@
/* Interrupt configuration for OSTM Timer*/
pulOSTMIntReg = ( volatile uint32_t * ) portOSTM_EIC_ADDR;
- *pulOSTMIntReg = ( portINT_TABLE_VECTOR | configTIMER_INT_PRIORITY );
+ *pulOSTMIntReg = ( portINT_DIRECT_VECTOR | configTIMER_INT_PRIORITY );
/* Set OSTM0 control setting */
- *( ( volatile uint32_t * ) portOSTMCTL_ADDR ) = ( portOSTM_INTERRUPT_ENABLE | portOSTM_MODE_INTERVAL_TIMER | portOSTM_START_INTERRUPT_DISABLE );
- *( ( volatile uint32_t * ) portOSTMCMP_ADDR ) = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) ) - 1;
+ *( ( volatile uint32_t * ) portOSTMCTL_ADDR ) =
+ ( portOSTM_INTERRUPT_ENABLE | portOSTM_MODE_INTERVAL_TIMER | portOSTM_START_INTERRUPT_DISABLE );
+ *( ( volatile uint32_t * ) portOSTMCMP_ADDR ) = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1 );
/* Enable OSTM0 operation */
*( ( volatile uint32_t * ) portOSTMTS_ADDR ) = portOSTM_COUNTER_START;
@@ -647,11 +625,13 @@
* before and after function call. */
push r20
mov # __s.mev_address.bss, r20
+
/* r6 is xBitPosition */
Lock: set1 r6, [ r20 ]
bz Lock_success
snooze
br Lock
+
Lock_success:
pop r20
}
@@ -663,13 +643,15 @@
{
push r20
mov # __s.mev_address.bss, r20
+
/* r6 is xBitPosition */
clr1 r6, [ r20 ]
pop r20
}
/*-----------------------------------------------------------*/
- void vPortRecursiveLockAcquire( BaseType_t xCoreID, BaseType_t xFromIsr )
+ void vPortRecursiveLockAcquire( BaseType_t xCoreID,
+ BaseType_t xFromIsr )
{
BaseType_t xSavedInterruptStatus;
BaseType_t xBitPosition = ( xFromIsr == pdTRUE );
@@ -685,7 +667,8 @@
portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus );
}
- void vPortRecursiveLockRelease( BaseType_t xCoreID, BaseType_t xFromIsr )
+ void vPortRecursiveLockRelease( BaseType_t xCoreID,
+ BaseType_t xFromIsr )
{
BaseType_t xSavedInterruptStatus;
BaseType_t xBitPosition = ( xFromIsr == pdTRUE );
diff --git a/CCRH/U2x/portasm.s b/CCRH/U2x/portasm.s
index 2b896d0..1c42c8d 100644
--- a/CCRH/U2x/portasm.s
+++ b/CCRH/U2x/portasm.s
@@ -26,40 +26,40 @@
; *
; */
-
;------------------------------------------------------------------------------
-; Extern symbols
+; Extern symbols.
;------------------------------------------------------------------------------
.extern _uxInterruptNesting
-.extern _uxPortMaxInterruptDepth
.extern _xPortScheduleStatus
.extern _vTaskSwitchContext
.extern _pvPortGetCurrentTCB
-.extern _vCommonISRHandler
.extern _xPortGET_CORE_ID
.public _vIrq_Handler
.public _vPortStartFirstTask
.public _vPortYield
.public _vTRAP0_Handler
+
;------------------------------------------------------------------------------
-; Macro definitions
+; Macro definitions.
;------------------------------------------------------------------------------
-EIPC .set 0
-EIPSW .set 1
-PSW .set 5
-FPSR .set 6
-FPEPC .set 7
-FXSR .set 6
-FXXP .set 13
-EIIC .set 13
-CTPC .set 16
-CTPSW .set 17
+EIPC .set 0
+EIPSW .set 1
+PSW .set 5
+FPSR .set 6
+FPEPC .set 7
+FXSR .set 6
+FXXP .set 13
+EIIC .set 13
+CTPC .set 16
+CTPSW .set 17
EIIC_MSK .set 0x00000FFF
+FPU_MSK .set 0x00010000
+FXU_MSK .set 0x00020000
;------------------------------------------------------------------------------
; portSAVE_CONTEXT
-; Context saving
+; Context saving.
;------------------------------------------------------------------------------
portSAVE_CONTEXT .macro
prepare lp, 0
@@ -71,33 +71,27 @@
$warning
stsr EIPSW, r15
+
+ ; Save FPU registers to stack if FPU is enabled.
+ ; If disable, skip next 2 instructions: stsr (4 bytes)*2 with dummy save.
+ $ifndef configDISABLE_FPU
+ mov FPU_MSK, r19
+ tst r15, r19
+ bz 10
+
+ stsr FPSR, r18
+ stsr FPEPC, r19
+ pushsp r18, r19 ; Push dummy value if FPU disabled.
+ $endif
+
+ stsr EIPSW, r15
stsr EIPC, r16
stsr EIIC, r17
stsr CTPSW, r18
stsr CTPC, r19
pushsp r15, r19
- ; Save FPU registers to stack if FPU is enabled
- $ifdef configENABLE_FPU
- stsr FPSR, r18
- stsr FPEPC, r19
- pushsp r18, r19
- $endif
-
- ; Save FXU registers to stack if FXU is enabled
- $ifdef configENABLE_FXU
- mov r0, r20
- mov r0, r21
- stsr 0, r19, 2 ; Get PEID
- cmp r19, r0 ; Confirm PEID value is PE0
- bne 8 ; Branch 2 instructions if is not PE0
- ; to avoid unprivileged access
- stsr FXSR, r20, 10 ; If PE0, save FXU register
- stsr FXXP, r21, 10 ; If PE0, save FXU register
- pushsp r20, r21
- $endif
-
- ; Get current TCB, the return value is stored in r10 (CCRH compiler)
+ ; Get current TCB, the return value is stored in r10 (CCRH compiler).
jarl _pvPortGetCurrentTCB, lp
st.w sp, 0[r10]
@@ -105,32 +99,14 @@
;------------------------------------------------------------------------------
; portRESTORE_CONTEXT
-; Context restoring
+; Context restoring.
;------------------------------------------------------------------------------
portRESTORE_CONTEXT .macro
- ; Current TCB is returned by r10 (CCRH compiler)
+ ; Current TCB is returned by r10 (CCRH compiler).
jarl _pvPortGetCurrentTCB, lp
- ld.w 0[r10], sp ; Restore the stack pointer from the TCB
+ ld.w 0[r10], sp ; Restore the stack pointer from the TCB.
- ; Restore FXU registers if FXU is enabled
- $ifdef configENABLE_FXU
- popsp r20, r21
- stsr 0, r19, 2 ; Get PEID
- cmp r19, r0 ; Confirm PEID value is PE0
- bne 8 ; Branch 2 instructions if is not PE0
- ; to avoid unprivileged access
- ldsr r21, FXXP, 10 ; If PE0, restore FXU register
- ldsr r20, FXSR, 10 ; If PE0, restore FXU register
- $endif
-
- ; Restore FPU registers if FPU is enabled
- $ifdef configENABLE_FPU
- popsp r18, r19
- ldsr r19, FPEPC
- ldsr r18, FPSR
- $endif
-
- ;Restore general-purpose registers and EIPSW, EIPC, EIIC, CTPSW, CTPC
+ ; Restore general-purpose registers and EIPSW, EIPC, EIIC, CTPSW, CTPC.
popsp r15, r19
ldsr r19, CTPC
ldsr r18, CTPSW
@@ -138,6 +114,16 @@
ldsr r16, EIPC
ldsr r15, EIPSW
+ ; Restore FPU registers if FPU is enabled.
+ $ifndef configDISABLE_FPU
+ popsp r18, r19
+ mov FPU_MSK, r17
+ tst r15, r17
+ bz 10
+ ldsr r19, FPEPC
+ ldsr r18, FPSR
+ $endif
+
$nowarning
popsp r1, r2
$warning
@@ -147,81 +133,83 @@
.endm
;------------------------------------------------------------------------------
-; Save used registers
+; Save used registers.
;------------------------------------------------------------------------------
SAVE_REGISTER .macro
; Save general-purpose registers and EIPSW, EIPC, EIIC, CTPSW, CTPC into stack.
; Callee-Save registers (r20 to r30) are not used in interrupt handler and
; guaranteed no change after function call. So, do not need to save register
; to optimize the used stack memory.
- pushsp r5, r21
+ pushsp r5, r19
$nowarning
pushsp r1, r2
$warning
- stsr EIPSW, r19
- stsr EIPC, r18
- stsr EIIC, r17
- mov lp, r16
- mov ep, r15
- stsr CTPSW, r14
- stsr CTPC, r13
- pushsp r13, r19
+ stsr EIPSW, r15
- $ifdef configENABLE_FPU
+ $ifndef configDISABLE_FPU
+ mov FPU_MSK, r19
+ tst r15, r19
+ bz 10
stsr FPSR, r18
stsr FPEPC, r19
- pushsp r18, r19
+ pushsp r18, r19 ; Push dummy value if FPU disabled.
$endif
- ; Save FXU registers to stack if FXU is enabled
- $ifdef configENABLE_FXU
- mov r0, r20
- mov r0, r21
- stsr 0, r19, 2 ; Get PEID
- cmp r19, r0 ; Confirm PEID value is PE0
- bne 8 ; Branch 2 instructions if is not PE0
- ; to avoid unprivileged access
- stsr FXSR, r20, 10 ; If PE0, save FXU register
- stsr FXXP, r21, 10 ; If PE0, save FXU register
- pushsp r20, r21
+ $ifndef configDISABLE_FXU
+ mov FXU_MSK, r19
+ tst r15, r19
+ bz 10
+ stsr FXSR, r18, 10
+ stsr FXXP, r19, 10
+ pushsp r18, r19 ; Push dummy value if FXU disabled.
$endif
+ mov ep, r13
+ mov lp, r14
+ stsr EIPSW, r15
+ stsr EIPC, r16
+ stsr EIIC, r17
+ stsr CTPSW, r18
+ stsr CTPC, r19
+ pushsp r13, r19
+
.endm
;------------------------------------------------------------------------------
-; Restore used registers
+; Restore used registers.
;------------------------------------------------------------------------------
RESTORE_REGISTER .macro
- ; Restore FXU registers if FXU is enabled
- $ifdef configENABLE_FXU
- popsp r20, r21
- stsr 0, r19, 2 ; Get PEID
- cmp r19, r0 ; Confirm PEID value is PE0
- bne 8 ; Branch 2 instructions if is not PE0
- ; to avoid unprivileged access
- ldsr r21, FXXP, 10 ; If PE0, restore FXU register
- ldsr r20, FXSR, 10 ; If PE0, restore FXU register
+ popsp r13, r19
+ ldsr r19, CTPC
+ ldsr r18, CTPSW
+ ldsr r17, EIIC
+ ldsr r16, EIPC
+ ldsr r15, EIPSW
+ mov r14, lp
+ mov r13, ep
+
+ $ifndef configDISABLE_FXU
+ popsp r18, r19
+ mov FXU_MSK, r17
+ tst r15, r17
+ bz 10
+ ldsr r19, FXXP, 10
+ ldsr r18, FXSR, 10
$endif
- $ifdef configENABLE_FPU
+ $ifndef configDISABLE_FPU
popsp r18, r19
+ mov FPU_MSK, r17
+ tst r15, r17
+ bz 10
ldsr r19, FPEPC
ldsr r18, FPSR
$endif
- popsp r13, r19
- ldsr r13, CTPC
- ldsr r14, CTPSW
- mov r15, ep
- mov r16, lp
- ldsr r17, EIIC
- ldsr r18, EIPC
- ldsr r19, EIPSW
-
$nowarning
popsp r1, r2
$warning
- popsp r5, r21
+ popsp r5, r19
.endm
;------------------------------------------------------------------------------
@@ -236,19 +224,19 @@
;------------------------------------------------------------------------------
_vPortYield:
trap 0
- jmp [lp] ; Return to caller function
+ jmp [lp] ; Return to caller function.
;------------------------------------------------------------------------------
; PortYield handler. This is installed as the TRAP exception handler.
;------------------------------------------------------------------------------
_vTRAP0_Handler:
- ;Save the context of the current task.
+ ; Save the context of the current task.
portSAVE_CONTEXT
; The use case that portYield() is called from interrupt context as nested interrupt.
; Context switch should be executed at the most outer of interrupt tree.
; In that case, set xPortScheduleStatus to flag context switch in interrupt handler.
- jarl _xPortGET_CORE_ID, lp ; return value is contained in r10 (CCRH compiler)
+ jarl _xPortGET_CORE_ID, lp ; return value is contained in r10 (CCRH compiler).
mov r10, r11
shl 2, r11
mov #_uxInterruptNesting, r19
@@ -288,9 +276,9 @@
; Save used registers.
SAVE_REGISTER
- ; Get core ID by HTCFG0, thread configuration register.
+ ; Get core ID by PEID, thread configuration register.
; Then, increase nesting count for current core.
- jarl _xPortGET_CORE_ID, lp ; return value is contained in r10 (CCRH compiler)
+ jarl _xPortGET_CORE_ID, lp ; return value is contained in r10 (CCRH compiler).
mov r10, r17
shl 2, r17
@@ -300,29 +288,43 @@
addi 0x1, r18, r16
st.w r16, 0[r19]
- pushsp r17, r19
+ ; Check and switch to interrupt stack if task stack is currently used.
+ cmp r0, r18
+ bne _vIrq_Handler_Entry_End
+ mov #_uxInterruptStack, r14
+ add r17, r14
+ ld.w 0[r14], r14
+ mov sp, r16
+ mov r14, sp
- ;Call the interrupt handler.
+_vIrq_Handler_Entry_End:
+ pushsp r16, r19
+
+ ; Call the interrupt handler.
stsr EIIC, r6
andi EIIC_MSK, r6, r6
- ; Do not enable interrupt for nesting. Stackover flow may occurs if the
- ; depth of nesting interrupt is exceeded.
- mov #_uxPortMaxInterruptDepth, r19
- ld.w 0[r19], r15
- cmp r15, r16
- bge 4 ; Jump over ei instruction
+ ; Enable nested interrupts, invoke ISR functions from reference table.
ei
- jarl _vCommonISRHandler, lp
+ stsr 4, r16, 1 ; Load based address of Interrupt Reference Table.
+ andi 0xfff, r6, r17
+ shl 2, r17
+ add r17, r16
+ ld.w 0[r16], r16
+
+ ; Invoke registered ISR function
+ jarl [r16], lp
+
di
synce
- popsp r17, r19
- st.w r18, 0[r19] ; Restore the old nesting count.
+ popsp r16, r19
+ st.w r18, 0[r19] ; Restore the old nesting count.
; A context switch if no nesting interrupt.
cmp 0x0, r18
bne _vIrq_Handler_NotSwitchContext
+ mov r16, sp ; Restore to task stack.
; Check if context switch is requested.
mov #_xPortScheduleStatus, r19
@@ -332,11 +334,11 @@
bne _vIrq_Handler_SwitchContext
_vIrq_Handler_NotSwitchContext:
- ; No context switch. Restore used registers
+ ; No context switch. Return to caller and exit interrupt.
RESTORE_REGISTER
eiret
-;This sequence is executed for primary core only to switch context
+; This sequence is executed for primary core only to switch context.
_vIrq_Handler_SwitchContext:
; Clear the context switch pending flag.
st.w r0, 0[r19]
@@ -347,13 +349,13 @@
RESTORE_REGISTER
portSAVE_CONTEXT
- ; Get Core ID and pass to vTaskSwitchContext as parameter (CCRH compiler)
- ; The parameter is unused in single core, no problem with this redudant setting
- jarl _xPortGET_CORE_ID, lp ; return value is contained in r10 (CCRH compiler)
+ ; Get Core ID and pass to vTaskSwitchContext as parameter (CCRH compiler).
+ ; The parameter is unused in single core, no problem with this redudant setting.
+ jarl _xPortGET_CORE_ID, lp ; return value is contained in r10 (CCRH compiler).
mov r10, r6
; vPortYeild may be called to current core again at the end of vTaskSwitchContext.
- ; This may case nested interrupt, however, it is not necessary to set
+ ; This may cause nested interrupt, however, it is not necessary to set
; uxInterruptNesting (currently 0) for trap0 exception. The user interrupt
; (EI level interrupt) is not accepted inside of trap0 exception.
jarl _vTaskSwitchContext, lp
@@ -361,6 +363,7 @@
eiret
_vIrq_Handler_StartFirstTask:
+ ; The stack is switch to task stack when starting the first task.
+ ; Save address of interrupt stack.
RESTORE_REGISTER
jr _vPortStartFirstTask
-
diff --git a/CCRH/U2x/portmacro.h b/CCRH/U2x/portmacro.h
index 1e2b7b4..b6b3e4b 100644
--- a/CCRH/U2x/portmacro.h
+++ b/CCRH/U2x/portmacro.h
@@ -82,22 +82,22 @@
#define portSYNCM() __syncm()
/* Specify 16 interrupt priority levels */
- #define portINT_PRIORITY_HIGHEST ( 0x0000U ) /* Level 0 (highest) */
- #define portINT_PRIORITY_LEVEL1 ( 0x0001U ) /* Level 1 */
- #define portINT_PRIORITY_LEVEL2 ( 0x0002U ) /* Level 2 */
- #define portINT_PRIORITY_LEVEL3 ( 0x0003U ) /* Level 3 */
- #define portINT_PRIORITY_LEVEL4 ( 0x0004U ) /* Level 4 */
- #define portINT_PRIORITY_LEVEL5 ( 0x0005U ) /* Level 5 */
- #define portINT_PRIORITY_LEVEL6 ( 0x0006U ) /* Level 6 */
- #define portINT_PRIORITY_LEVEL7 ( 0x0007U ) /* Level 7 */
- #define portINT_PRIORITY_LEVEL8 ( 0x0008U ) /* Level 8 */
- #define portINT_PRIORITY_LEVEL9 ( 0x0009U ) /* Level 9 */
- #define portINT_PRIORITY_LEVEL10 ( 0x000AU ) /* Level 10 */
- #define portINT_PRIORITY_LEVEL11 ( 0x000BU ) /* Level 11 */
- #define portINT_PRIORITY_LEVEL12 ( 0x000CU ) /* Level 12 */
- #define portINT_PRIORITY_LEVEL13 ( 0x000DU ) /* Level 13 */
- #define portINT_PRIORITY_LEVEL14 ( 0x000EU ) /* Level 14 */
- #define portINT_PRIORITY_LOWEST ( 0x000FU ) /* Level 15 (lowest) */
+ #define portINT_PRIORITY_HIGHEST ( 0x0000U ) /* Level 0 (highest) */
+ #define portINT_PRIORITY_LEVEL1 ( 0x0001U ) /* Level 1 */
+ #define portINT_PRIORITY_LEVEL2 ( 0x0002U ) /* Level 2 */
+ #define portINT_PRIORITY_LEVEL3 ( 0x0003U ) /* Level 3 */
+ #define portINT_PRIORITY_LEVEL4 ( 0x0004U ) /* Level 4 */
+ #define portINT_PRIORITY_LEVEL5 ( 0x0005U ) /* Level 5 */
+ #define portINT_PRIORITY_LEVEL6 ( 0x0006U ) /* Level 6 */
+ #define portINT_PRIORITY_LEVEL7 ( 0x0007U ) /* Level 7 */
+ #define portINT_PRIORITY_LEVEL8 ( 0x0008U ) /* Level 8 */
+ #define portINT_PRIORITY_LEVEL9 ( 0x0009U ) /* Level 9 */
+ #define portINT_PRIORITY_LEVEL10 ( 0x000AU ) /* Level 10 */
+ #define portINT_PRIORITY_LEVEL11 ( 0x000BU ) /* Level 11 */
+ #define portINT_PRIORITY_LEVEL12 ( 0x000CU ) /* Level 12 */
+ #define portINT_PRIORITY_LEVEL13 ( 0x000DU ) /* Level 13 */
+ #define portINT_PRIORITY_LEVEL14 ( 0x000EU ) /* Level 14 */
+ #define portINT_PRIORITY_LOWEST ( 0x000FU ) /* Level 15 (lowest) */
/* Determine the descending of the stack from high address to address */
#define portSTACK_GROWTH ( -1 )
@@ -162,8 +162,10 @@
#define portGET_TASK_LOCK( xCoreID )
#define portRELEASE_TASK_LOCK( xCoreID )
#else
- extern void vPortRecursiveLockAcquire( BaseType_t xCoreID, BaseType_t xFromIsr );
- extern void vPortRecursiveLockRelease( BaseType_t xCoreID, BaseType_t xFromIsr );
+ extern void vPortRecursiveLockAcquire( BaseType_t xCoreID,
+ BaseType_t xFromIsr );
+ extern void vPortRecursiveLockRelease( BaseType_t xCoreID,
+ BaseType_t xFromIsr );
#define portGET_ISR_LOCK( xCoreID ) vPortRecursiveLockAcquire( ( xCoreID ), pdTRUE )
#define portRELEASE_ISR_LOCK( xCoreID ) vPortRecursiveLockRelease( ( xCoreID ), pdTRUE )
@@ -204,6 +206,6 @@
/*-----------------------------------------------------------*/
#ifdef __cplusplus
-}
+ }
#endif
#endif /* PORTMACRO_H */
diff --git a/GHS/U2x/README.md b/GHS/U2x/README.md
index 01a7a7c..7b386ab 100644
--- a/GHS/U2x/README.md
+++ b/GHS/U2x/README.md
@@ -18,24 +18,111 @@
## Link to Test Project
-The test project can be found in [RH850_U2Ax_GHS](https://github.com/FreeRTOS/FreeRTOS-Partner-Supported-Demos/tree/main/RH850_U2Ax_GHS) and [RH850_U2Bx_GHS](https://github.com/FreeRTOS/FreeRTOS-Partner-Supported-Demos/tree/main/RH850_U2Bx_GHS). These projects contain example tasks and configurations to help you get started with FreeRTOS on the RH850/U2Ax and U2Bx.
+The test project can be found in [RH850_U2Ax_GHS](https://github.com/FreeRTOS/FreeRTOS-Partner-Supported-Demos/tree/main/RH850_U2Ax_GHS) and [RH850_U2Bx_GHS](https://github.com/FreeRTOS/FreeRTOS-Partner-Supported-Demos/tree/main/RH850_U2Bx_GHS). These projects contain example tasks and configurations to help you get started with FreeRTOS on the RH850/U2Ax and RH850/U2Bx.
+
+## Setup for Vector Table
+ 1. Allocate the Stack area in Linker Script:<br />
+ - In the Linker configuration, create a dedicated Stack (memory region) for the Vector Table of each Processing Element (PE).
+
+ For example:<br />
+ <pre>
+ .inttable_PE0 0x00020000 align(4) :>.
+ .inttable_PE1 0x00024000 align(4) :>.
+ .inttable_PE2 0x00028000 align(4) :>.
+ </pre>
+
+ 2. Declare the Vector Table in the source code:<br />
+ - In the application source code, define the Vector Table.<br />
+ - Map this Vector Table to the Stack region that was created in the Linker Script.
+
+ For example, in **main.c** file, add:<br />
+ <pre>
+ /***********************************************************************************************************************
+ * Vector Table Configuration
+ **********************************************************************************************************************/
+ /* Interrupt vector table for PE0. Mapping into the memory section ".inttable_PE0". */
+ #pragma ghs section rodata=".inttable_PE0"
+ const int_vector_t g_vector_table_PE0[ 365 ] =
+ {
+ [ 1 ] = vPortIPIHander, /* Internal processor interrupt 1 */
+ [ 360 ] = vPortTickISR, /* INTOSTM0TINT (OSTM0 interrupt) */
+ };
+
+ /* Interrupt vector table for PE1. Mapping into the memory section ".inttable_PE1". */
+ #pragma ghs section rodata=".inttable_PE1"
+ const int_vector_t g_vector_table_PE1[ 365 ] =
+ {
+ [ 1 ] = vPortIPIHander, /* Internal processor interrupt 1 */
+ };
+
+ /* Interrupt vector table for PE2. Mapping into the memory section ".inttable_PE2". */
+ #pragma ghs section rodata=".inttable_PE2"
+ const int_vector_t g_vector_table_PE2[ 365 ] =
+ {
+ [ 1 ] = vPortIPIHander, /* Internal processor interrupt 1 */
+ };
+
+ #pragma ghs section text=default
+ </pre>
+
+ 3. Assign the Vector Table into the INTBP register in Startup:<br />
+ - In System Startup, assign the Vector Table address into the INTBP register so that the Processor knows where to fetch Interrupt Vectors.
+
+ For example, in **Startup** file, add:<br />
+ <pre>
+ -------------------------------------------------------------------------------
+ ------------- PE1 Specific Startup Routine
+ -------------------------------------------------------------------------------
+ #if defined (PE1_USED)
+ _INIT_PE1:
+ -- Initialization of the interrupt base pointer
+ mov _g_vector_table_PE1, r1
+ ldsr r1, INTBP, 1
+ #endif
+
+ -------------------------------------------------------------------------------
+ ------------- PE2 Specific Startup Routine
+ -------------------------------------------------------------------------------
+ #if defined (PE2_USED)
+ _INIT_PE2:
+ -- Initialization of the interrupt base pointer
+ mov _g_vector_table_PE2, r1
+ ldsr r1, INTBP, 1
+ #endif
+ </pre>
+
+ 4. Interrupt Vector Configuration:<br />
+ - Interrupt handling must be configured using the Direct Vector method, e.g. by configuring EBASE or EICn registers.
+
+## FPU and FXU Units Usage
+ - The `FXU Unit` is available only on RH850 U2Bx devices.<br />
+ To ensure correct operation, any task requiring FXU must run on an FXU-enabled core. In SMP systems, the core assignment shall be fixed using CPU affinity via the `vTaskCoreAffinitySet()` function.
+
+ - By default, the FPU and FXU operations are enabled, which may introduce redundant code and impact performance.<br />
+ If they are not required by the application, FPU and FXU related code can be disabled by defining the macros `configDISABLE_FPU` and `configDISABLE_FXU` respectively.<br />
+ Additionally, `-DconfigDISABLE_FPU` and `-DconfigDISABLE_FXU` should be added to the build flags.
+
+ For example, in **make** file of GHS, add the CPU Flag:<br />
+ <pre>
+ AFLAGS += -DconfigDISABLE_FPU
+ AFLAGS += -DconfigDISABLE_FXU
+ </pre>
## Note
- 1. The minimal stack size `configMINIMAL_STACK_SIZE` must be included the reserved memory for nested interrupt. This formula can be referred: `(task_context_size) * (2 + configMAX_INT_NESTING) + Stack_depth_of_taskcode`
- In which, `task_context_size` is calculated as `36*4bytes = 144bytes` (when FPU enabled) or `34*4bytes = 136` (when FPU disabled), configMAX_INT_NESTING is `02` as default (Note that a value of `0` is not allowed).
+ 1. Refer this formula to estimate the minimal stack size (configMINIMAL_STACK_SIZE) used: `[(task_context_size) * 2] + stack_required_for_taskcode`.<br />
+ In which, `task_context_size` is calculated as `36 * 4 bytes = 144 bytes`.
+
2. Users need to create a memory section named `mev_address` in `CRAM` for Exclusive Control functionality. Users should initialize the `mev_address` section in the startup file.
-Example:
- ```
- -- .mev_address section in CRAM is used for Sync flags
- mov ___ghsbegin_mev_address, r20
- st.w r0, 0[r20]
- ```
- 3. The `FXU unit` is only available on `core 0`. Users must ensure that FXU operations are restricted to `core 0` by using the `vTaskCoreAffinitySet` function provided by FreeRTOS SMP.
- 4. Set the macro `configENABLE_FXU` to `1` to enable the `FXU unit`; otherwise set `0` to disable `FXU unit`.
- 5. This port supports both U2Ax and U2Bx devices. The user must configure `configDEVICE_NAME` with the value `U2Bx_DEVICES` or `U2Ax_DEVICES` to specify which device is being used.
- 6. The User can configure the interrupt priority of the OSTM Timer using `configTIMER_INT_PRIORITY`, with 16 levels available (0 being the highest priority and 15 the lowest).
- 7. This port also supports the configuration of contiguous CPU cores in FreeRTOS, allowing the user to set task affinity for execution on specific cores or subsets of cores.
+ For example:<br />
+ <pre>
+ -- .mev_address section in CRAM is used for Sync flags
+ mov ___ghsbegin_mev_address, r20
+ st.w r0, 0[r20]</pre>
+
+ 3. This port supports both U2Ax and U2Bx devices. The User must configure `configDEVICE_NAME` with the value `U2Bx_DEVICES` or `U2Ax_DEVICES` to specify which device is being used.
+
+ 4. This port also supports the configuration of contiguous CPU cores in FreeRTOS SMP, allowing the User to set task affinity for execution on specific cores or subsets of cores.
## Other Relevant Information
@@ -49,4 +136,4 @@
- If you encounter any issues or have questions about this port, please open an issue in this repository or contact the maintainer.
- **Contributing:**
- - Contributions to improve this port are welcome. Please fork the repository, make your changes, and submit a pull request.
\ No newline at end of file
+ - Contributions to improve this port are welcome. Please fork the repository, make your changes, and submit a pull request.
diff --git a/GHS/U2x/port.c b/GHS/U2x/port.c
index 9676b0a..5149301 100644
--- a/GHS/U2x/port.c
+++ b/GHS/U2x/port.c
@@ -46,7 +46,7 @@
#define portFXSR_REGISTER_SEL ( 10 )
/* PSW.EBV and PSW.CUx bits are kept as current status */
-#define portINITIAL_PSW_MASK ( 0x00078000 )
+#define portINITIAL_PSW_MASK ( 0x00038000 )
#define portCURRENT_PSW_VALUE ( portSTSR( portPSW_REGISTER_ID, portREGISTER_SEL_0 ) )
#define portCURRENT_SR_ZERO_VALUE ( ( StackType_t ) 0x00000000 )
#define portCURRENT_FPSR_VALUE ( portSTSR( portFPSR_REGISTER_ID, portREGISTER_SEL_0 ) )
@@ -141,8 +141,8 @@
/* Macros indicatings status of scheduler request */
#define PORT_SCHEDULER_NOREQUEST 0UL
-#define PORT_SCHEDULER_TASKSWITCH 1UL /* Do not modify */
-#define PORT_SCHEDULER_STARTFIRSTTASK 2UL /* Do not modify */
+#define PORT_SCHEDULER_TASKSWITCH 1UL /* Do not modify */
+#define PORT_SCHEDULER_STARTFIRSTTASK 2UL /* Do not modify */
#ifndef configSETUP_TICK_INTERRUPT
@@ -151,19 +151,6 @@
#define configSETUP_TICK_INTERRUPT() prvSetupTimerInterrupt()
#endif /* configSETUP_TICK_INTERRUPT */
-#if ( !defined( configMAX_INT_NESTING ) || ( configMAX_INT_NESTING == 0 ) )
-
-/* Set the default value for depth of nested interrupt. In theory, the
- * microcontroller have mechanism to limit number of nested level of interrupt
- * by priority (maximum 16 levels). However, the large stack memory should be
- * prepared for each task to save resource in interrupt handler. Therefore, it
- * is necessary to limit depth of nesting interrupt to optimize memory usage.
- * In addition, the execution time of interrupt handler should be very short
- * (typically not exceed 20us), this constraint does not impact to system.
- */
- #define configMAX_INT_NESTING 2UL
-#endif
-
/*
* Used to catch tasks that attempt to return from their implementing function.
*/
@@ -191,7 +178,11 @@
* It is necessary to control maximum stack depth.
*/
volatile UBaseType_t uxInterruptNesting[ configNUMBER_OF_CORES ] = { 0 };
-volatile const UBaseType_t uxPortMaxInterruptDepth = configMAX_INT_NESTING;
+
+#ifndef configPORT_ISR_STACK_TOPS
+ #error "Define configPORT_ISR_STACK_TOPS in FreeRTOSConfig.h"
+#endif
+const UBaseType_t uxInterruptStack[ configNUMBER_OF_CORES ] = configPORT_ISR_STACK_TOPS;
/* Count number of nested locks by same cores. The lock is completely released
* only if this count is decreased to 0, the lock is separated for task and isr */
@@ -224,8 +215,10 @@
* cores. The core will wait until lock will be available, whilst the core which
* already had lock can acquire lock without waiting. This function could be
* call from task and interrupt context, the critical section is called as in ISR */
- void vPortRecursiveLockAcquire( BaseType_t xCoreID, BaseType_t xFromIsr );
- void vPortRecursiveLockRelease( BaseType_t xCoreID, BaseType_t xFromIsr );
+ void vPortRecursiveLockAcquire( BaseType_t xCoreID,
+ BaseType_t xFromIsr );
+ void vPortRecursiveLockRelease( BaseType_t xCoreID,
+ BaseType_t xFromIsr );
#endif /* (configNUMBER_OF_CORES > 1) */
@@ -269,7 +262,7 @@
BaseType_t xPortGET_CORE_ID( void )
{
#if ( configNUMBER_OF_CORES > 1 )
- return( portSTSR( 0, 2 ) ); /* Get PEID value */
+ return portSTSR( 0, 2 ); /* Get PEID value */
#else
/* In single core, xPortGET_CORE_ID is used in this port only. The dummy
@@ -381,46 +374,31 @@
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R30; /* R30 (EP) */
pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R1; /* R1 */
+ *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R1; /* R1 */
pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R2; /* R2 */
+ *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R2; /* R2 */
+ pxTopOfStack--;
- pxTopOfStack--;
+ /* if FPU is enabled, initialize the FPU registers in Stack */
+ #ifndef configDISABLE_FPU
+ {
+ *pxTopOfStack = ( StackType_t ) ( portCURRENT_FPSR_VALUE & portINITIAL_FPSR_MASK ); /* FPSR */
+ pxTopOfStack--;
+ *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* FPEPC */
+ pxTopOfStack--;
+ }
+ #endif /* End of #ifndef configDISABLE_FPU */
/* Keep System pre-configuration (HV, CUx, EBV) as current setting in PSW register */
*pxTopOfStack = ( StackType_t ) ( portCURRENT_PSW_VALUE & portINITIAL_PSW_MASK ); /* EIPSW */
pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) pxCode; /* EIPC */
+ *pxTopOfStack = ( StackType_t ) pxCode; /* EIPC */
pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* EIIC */
+ *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* EIIC */
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) ( portCURRENT_PSW_VALUE & portINITIAL_PSW_MASK ); /* CTPSW */
pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* CTPC */
-
- /* if FPU is enabled, initialize the FPU registers in Stack */
- #if ( configENABLE_FPU == 1 )
- pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) ( portCURRENT_FPSR_VALUE & portINITIAL_FPSR_MASK ); /* FPSR */
- pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* FPEPC */
- #endif /* (configENABLE_FPU == 1) */
-
- /* if FXU is enabled, initialize the FXU registers in Stack */
- #if ( configENABLE_FXU == 1 )
- /* FXU Unit is available in PE0 only */
- if( 0 == xPortGET_CORE_ID() )
- {
- pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) ( portCURRENT_FXSR_VALUE & portINITIAL_FXSR_MASK ); /* FXSR */
- pxTopOfStack--;
- *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* FXXP */
- }
- else
- {
- /* Do nothing */
- }
- #endif /* (configENABLE_FXU == 1) */
+ *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* CTPC */
return pxTopOfStack;
}
@@ -494,9 +472,7 @@
* should instead call vTaskDelete( NULL ).
*
* Artificially force an assert() to be triggered if configASSERT() is
- * defined, then stop here so application writers can catch the error. */
-
- /* This statement will always fail, triggering the assert */
+ * defined, then stop here so application writers can catch the error. *//* This statement will always fail, triggering the assert */
configASSERT( pdFALSE );
/*
@@ -621,10 +597,11 @@
/* Interrupt configuration for OSTM Timer*/
pulOSTMIntReg = ( volatile uint32_t * ) portOSTM_EIC_ADDR;
- *pulOSTMIntReg = ( portINT_TABLE_VECTOR | configTIMER_INT_PRIORITY );
+ *pulOSTMIntReg = ( portINT_DIRECT_VECTOR | configTIMER_INT_PRIORITY );
/* Set OSTM0 control setting */
- *( ( volatile uint32_t * ) portOSTMCTL_ADDR ) = ( portOSTM_INTERRUPT_ENABLE | portOSTM_MODE_INTERVAL_TIMER | portOSTM_START_INTERRUPT_DISABLE );
+ *( ( volatile uint32_t * ) portOSTMCTL_ADDR ) =
+ ( portOSTM_INTERRUPT_ENABLE | portOSTM_MODE_INTERVAL_TIMER | portOSTM_START_INTERRUPT_DISABLE );
*( ( volatile uint32_t * ) portOSTMCMP_ADDR ) = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1 );
/* Enable OSTM0 operation */
@@ -665,7 +642,8 @@
}
/*-----------------------------------------------------------*/
- void vPortRecursiveLockAcquire( BaseType_t xCoreID, BaseType_t xFromIsr )
+ void vPortRecursiveLockAcquire( BaseType_t xCoreID,
+ BaseType_t xFromIsr )
{
BaseType_t xSavedInterruptStatus;
BaseType_t xBitPosition = ( xFromIsr == pdTRUE );
@@ -681,7 +659,8 @@
portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus );
}
- void vPortRecursiveLockRelease( BaseType_t xCoreID, BaseType_t xFromIsr )
+ void vPortRecursiveLockRelease( BaseType_t xCoreID,
+ BaseType_t xFromIsr )
{
BaseType_t xSavedInterruptStatus;
BaseType_t xBitPosition = ( xFromIsr == pdTRUE );
diff --git a/GHS/U2x/portasm.850 b/GHS/U2x/portasm.850
index 0561ed0..f184626 100644
--- a/GHS/U2x/portasm.850
+++ b/GHS/U2x/portasm.850
@@ -26,40 +26,40 @@
-- *
-- */
-#include "FreeRTOSConfig.h"
-
-------------------------------------------------------------------------------
--- Extern symbols
+-- Extern symbols.
-------------------------------------------------------------------------------
.extern _uxInterruptNesting
-.extern _uxPortMaxInterruptDepth
.extern _xPortScheduleStatus
.extern _vTaskSwitchContext
.extern _pvPortGetCurrentTCB
-.extern _vCommonISRHandler
.extern _xPortGET_CORE_ID
.global _vIrq_Handler
.global _vPortStartFirstTask
.global _vPortYield
.global _vTRAP0_Handler
+
--------------------------------------------------------------------------------
--- Macro definitions
+-- Macro definitions.
--------------------------------------------------------------------------------
-.set EIPC, 0
-.set EIPSW, 1
-.set PSW, 5
-.set FPSR, 6
-.set FPEPC, 7
-.set FXSR, 6
-.set FXXP, 13
-.set EIIC, 13
-.set CTPC, 16
-.set CTPSW, 17
+.set EIPC, 0
+.set EIPSW, 1
+.set PSW, 5
+.set FPSR, 6
+.set FPEPC, 7
+.set FXSR, 6
+.set FXXP, 13
+.set EIIC, 13
+.set CTPC, 16
+.set CTPSW, 17
.set EIIC_MSK, 0x00000FFF
+.set FPU_MSK, 0x00010000
+.set FXU_MSK, 0x00020000
+
--------------------------------------------------------------------------------
-- portSAVE_CONTEXT
--- Context saving
+-- Context saving.
--------------------------------------------------------------------------------
.macro portSAVE_CONTEXT
prepare {lp}, 0
@@ -71,66 +71,39 @@
--$warning
stsr EIPSW, r15
+ -- Save FPU registers to stack if they are enabled.
+ -- If disable, skip next 2 instructions: stsr (4 bytes)*2 with dummy save.
+ #ifndef configDISABLE_FPU
+ mov FPU_MSK, r19
+ tst r15, r19
+ bz 10
+ stsr FPSR, r18
+ stsr FPEPC, r19
+ pushsp r18-r19 -- Push dummy value if FPU disabled.
+ #endif
+
+ stsr EIPSW, r15
stsr EIPC, r16
stsr EIIC, r17
stsr CTPSW, r18
stsr CTPC, r19
pushsp r15-r19
- -- Save FPU registers to stack if FPU is enabled
- #if (1 == configENABLE_FPU)
- stsr FPSR, r18
- stsr FPEPC, r19
- pushsp r18-r19
- #endif
-
- -- Save FXU registers to stack if FXU is enabled
- #if (1 == configENABLE_FXU)
- mov r0, r20
- mov r0, r21
- stsr 0, r19, 2 -- Get PEID
- cmp r19, r0 -- Confirm PEID value is PE0
- bne 8 -- branch 2 instructions if is not PE0
- -- to avoid unprivileged access
- stsr FXSR, r20, 10 -- If PE0, save FXU register
- stsr FXXP, r21, 10 -- If PE0, save FXU register
- pushsp r20-r21
- #endif
-
- -- Get current TCB, the return value is stored in r10
+ -- Get current TCB, the return value is stored in r10.
jarl _pvPortGetCurrentTCB, lp
st.w sp, 0[r10]
-
.endm
--------------------------------------------------------------------------------
-- portRESTORE_CONTEXT
--- Context restoring
+-- Context restoring.
--------------------------------------------------------------------------------
.macro portRESTORE_CONTEXT
- -- Current TCB is returned by r10
+ -- Current TCB is returned by r10.
jarl _pvPortGetCurrentTCB, lp
- ld.w 0[r10], sp -- Restore the stack pointer from the TCB
+ ld.w 0[r10], sp -- Restore the stack pointer from the TCB.
- -- Restore FXU registers if FXU is enabled
- #if (1 == configENABLE_FXU)
- popsp r20-r21
- stsr 0, r19, 2 -- Get PEID
- cmp r19, r0 -- Confirm PEID value is PE0
- bne 8 -- branch 2 instructions if is not PE0
- -- to avoid unprivileged access
- ldsr r21, FXXP, 10 -- If PE0, restore FXU register
- ldsr r20, FXSR, 10 -- If PE0, restore FXU register
- #endif
-
- -- Restore FPU registers if FPU is enabled
- #if (1 == configENABLE_FPU)
- popsp r18-r19
- ldsr r19, FPEPC
- ldsr r18, FPSR
- #endif
-
- --Restore general-purpose registers and EIPSW, EIPC, EIIC, CTPSW, CTPC
+ -- Restore general-purpose registers and EIPSW, EIPC, EIIC, CTPSW, CTPC.
popsp r15-r19
ldsr r19, CTPC
ldsr r18, CTPSW
@@ -138,6 +111,16 @@
ldsr r16, EIPC
ldsr r15, EIPSW
+ -- Restore FPU registers if FPU is enabled.
+ #ifndef configDISABLE_FPU
+ popsp r18-r19
+ mov FPU_MSK, r17
+ tst r15, r17
+ bz 10
+ ldsr r19, FPEPC
+ ldsr r18, FPSR
+ #endif
+
--$nowarning
popsp r1-r2
--$warning
@@ -147,77 +130,82 @@
.endm
--------------------------------------------------------------------------------
--- Save used registers
+-- Save used registers.
--------------------------------------------------------------------------------
.macro SAVE_REGISTER
- pushsp r5-r30
+ pushsp r5-r19
--$nowarning
pushsp r1-r2
--$warning
- stsr EIPSW, r19
- stsr EIPC, r18
- stsr EIIC, r17
- mov lp, r16
- mov ep, r15
- stsr CTPSW, r14
- stsr CTPC, r13
- pushsp r13-r19
+ stsr EIPSW, r15
- #if (1 == configENABLE_FPU)
+ #ifndef configDISABLE_FPU
+ mov FPU_MSK, r19
+ tst r15, r19
+ bz 10
stsr FPSR, r18
stsr FPEPC, r19
- pushsp r18-r19
+ pushsp r18-r19 -- Push dummy value if FPU disabled.
#endif
- -- Save FXU registers to stack if FXU is enabled
- #if (1 == configENABLE_FXU)
- mov r0, r20
- mov r0, r21
- stsr 0, r19, 2 -- Get PEID
- cmp r19, r0 -- Confirm PEID value is PE0
- bne 8 -- Branch 2 instructions if is not PE0
- -- to avoid unprivileged access
- stsr FXSR, r20, 10 -- If PE0, save FXU register
- stsr FXXP, r21, 10 -- If PE0, save FXU register
- pushsp r20-r21
+ -- Save FXU registers to stack if FXU is enabled.
+ #ifndef configDISABLE_FXU
+ mov FXU_MSK, r19
+ tst r15, r19
+ bz 10
+ stsr FXSR, r18, 10
+ stsr FXXP, r19, 10
+ pushsp r18-r19 -- Push dummy value if FXU disabled.
#endif
+ mov ep, r13
+ mov lp, r14
+ stsr EIPSW, r15
+ stsr EIPC, r16
+ stsr EIIC, r17
+ stsr CTPSW, r18
+ stsr CTPC, r19
+ pushsp r13-r19
+
.endm
--------------------------------------------------------------------------------
--- Restore used registers
+-- Restore used registers.
--------------------------------------------------------------------------------
.macro RESTORE_REGISTER
- -- Restore FXU registers if FXU is enabled
- #if (1 == configENABLE_FXU)
- popsp r20-r21
- stsr 0, r19, 2 -- Get PEID
- cmp r19, r0 -- Confirm PEID value is PE0
- bne 8 -- Branch 2 instructions if is not PE0
- -- to avoid unprivileged access
- ldsr r21, FXXP, 10 -- If PE0, restore FXU register
- ldsr r20, FXSR, 10 -- If PE0, restore FXU register
+ popsp r13-r19
+ ldsr r19, CTPC
+ ldsr r18, CTPSW
+ ldsr r17, EIIC
+ ldsr r16, EIPC
+ ldsr r15, EIPSW
+ mov r14, lp
+ mov r13, ep
+
+ -- Restore FXU registers if FXU is enabled.
+ #ifndef configDISABLE_FXU
+ popsp r18-r19
+ mov FXU_MSK, r17
+ tst r15, r17
+ bz 10
+ ldsr r19, FXXP, 10
+ ldsr r18, FXSR, 10
#endif
- #if (1 == configENABLE_FPU)
+ -- Restore FPU registers if FPU is enabled.
+ #ifndef configDISABLE_FPU
popsp r18-r19
+ mov FPU_MSK, r17
+ tst r15, r17
+ bz 10
ldsr r19, FPEPC
ldsr r18, FPSR
#endif
- popsp r13-r19
- ldsr r13, CTPC
- ldsr r14, CTPSW
- mov r15, ep
- mov r16, lp
- ldsr r17, EIIC
- ldsr r18, EIPC
- ldsr r19, EIPSW
-
--$nowarning
popsp r1-r2
--$warning
- popsp r5-r30
+ popsp r5-r19
.endm
--------------------------------------------------------------------------------
@@ -232,19 +220,19 @@
--------------------------------------------------------------------------------
_vPortYield:
trap 0
- jmp [lp] -- Return to caller function
+ jmp [lp] -- Return to caller function.
--------------------------------------------------------------------------------
-- PortYield handler. This is installed as the TRAP exception handler.
--------------------------------------------------------------------------------
_vTRAP0_Handler:
- --Save the context of the current task.
+ -- Save the context of the current task.
portSAVE_CONTEXT
-- The use case that portYield() is called from interrupt context as nested interrupt.
-- Context switch should be executed at the most outer of interrupt tree.
-- In that case, set xPortScheduleStatus to flag context switch in interrupt handler.
- jarl _xPortGET_CORE_ID, lp -- return value is contained in r10
+ jarl _xPortGET_CORE_ID, lp -- return value is contained in r10.
mov r10, r11
shl 2, r11
mov _uxInterruptNesting, r19
@@ -284,11 +272,11 @@
-- Save used registers.
SAVE_REGISTER
- -- Get core ID by HTCFG0, thread configuration register.
+ -- Get core ID by PEID, thread configuration register.
-- Then, increase nesting count for current core.
- jarl _xPortGET_CORE_ID, lp -- return value is contained in r10
+ jarl _xPortGET_CORE_ID, lp -- return value is contained in r10.
mov r10, r17
- shl 2, r17
+ shl 2, r17
mov _uxInterruptNesting, r19
add r17, r19
@@ -296,29 +284,43 @@
addi 0x1, r18, r16
st.w r16, 0[r19]
- pushsp r17-r19
+ -- Check and switch to interrupt stack if task stack is currently used.
+ cmp r0, r18
+ bne _vIrq_Handler_Entry_End
+ mov _uxInterruptStack, r14
+ add r17, r14
+ ld.w 0[r14], r14
+ mov sp, r16
+ mov r14, sp
- --Call the interrupt handler.
+_vIrq_Handler_Entry_End:
+ pushsp r16-r19
+
+ -- Call the interrupt handler.
stsr EIIC, r6
andi EIIC_MSK, r6, r6
- -- Do not enable interrupt for nesting. Stackover flow may occurs if the
- -- depth of nesting interrupt is exceeded.
- mov _uxPortMaxInterruptDepth, r19
- ld.w 0[r19], r15
- cmp r15, r16
- bge 4 -- Jump over ei instruction
+ -- Enable nested interrupts, invoke ISR functions from reference table.
ei
- jarl _vCommonISRHandler, lp
+ stsr 4, r16, 1 -- Load based address of Interrupt Reference Table.
+ andi 0xfff, r6, r17
+ shl 2, r17
+ add r17, r16
+ ld.w 0[r16], r16
+
+ -- Invoke registered ISR function.
+ jarl [r16], lp
+
di
synce
- popsp r17-r19
- st.w r18, 0[r19] -- Restore the old nesting count.
+ popsp r16-r19
+ st.w r18, 0[r19] -- Restore the old nesting count.
-- A context switch if no nesting interrupt.
cmp 0x0, r18
bne _vIrq_Handler_NotSwitchContext
+ mov r16, sp -- Restore to task stack.
-- Check if context switch is requested.
mov _xPortScheduleStatus, r19
@@ -328,11 +330,11 @@
bne _vIrq_Handler_SwitchContext
_vIrq_Handler_NotSwitchContext:
- -- No context switch. Restore used registers
+ -- No context switch. Return to caller and exit interrupt.
RESTORE_REGISTER
eiret
---This sequence is executed for primary core only to switch context
+-- This sequence is executed for primary core only to switch context.
_vIrq_Handler_SwitchContext:
-- Clear the context switch pending flag.
st.w r0, 0[r19]
@@ -343,13 +345,13 @@
RESTORE_REGISTER
portSAVE_CONTEXT
- -- Get Core ID and pass to vTaskSwitchContext as parameter
- -- The parameter is unused in single core, no problem with this redudant setting
- jarl _xPortGET_CORE_ID, lp -- return value is contained in r10
+ -- Get Core ID and pass to vTaskSwitchContext as parameter.
+ -- The parameter is unused in single core, no problem with this redudant setting.
+ jarl _xPortGET_CORE_ID, lp -- return value is contained in r10.
mov r10, r6
-- vPortYeild may be called to current core again at the end of vTaskSwitchContext.
- -- This may case nested interrupt, however, it is not necessary to set
+ -- This may cause nested interrupt, however, it is not necessary to set
-- uxInterruptNesting (currently 0) for trap0 exception. The user interrupt
-- (EI level interrupt) is not accepted inside of trap0 exception.
jarl _vTaskSwitchContext, lp
@@ -357,6 +359,7 @@
eiret
_vIrq_Handler_StartFirstTask:
+ -- The stack is switch to task stack when starting the first task.
+ -- Save address of interrupt stack.
RESTORE_REGISTER
jr _vPortStartFirstTask
-
diff --git a/GHS/U2x/portmacro.h b/GHS/U2x/portmacro.h
index fcd7ebb..c9116b3 100644
--- a/GHS/U2x/portmacro.h
+++ b/GHS/U2x/portmacro.h
@@ -93,22 +93,22 @@
#define portSYNCM( void ) __asm( "syncm" )
/* Specify 16 interrupt priority levels */
- #define portINT_PRIORITY_HIGHEST ( 0x0000U ) /* Level 0 (highest) */
- #define portINT_PRIORITY_LEVEL1 ( 0x0001U ) /* Level 1 */
- #define portINT_PRIORITY_LEVEL2 ( 0x0002U ) /* Level 2 */
- #define portINT_PRIORITY_LEVEL3 ( 0x0003U ) /* Level 3 */
- #define portINT_PRIORITY_LEVEL4 ( 0x0004U ) /* Level 4 */
- #define portINT_PRIORITY_LEVEL5 ( 0x0005U ) /* Level 5 */
- #define portINT_PRIORITY_LEVEL6 ( 0x0006U ) /* Level 6 */
- #define portINT_PRIORITY_LEVEL7 ( 0x0007U ) /* Level 7 */
- #define portINT_PRIORITY_LEVEL8 ( 0x0008U ) /* Level 8 */
- #define portINT_PRIORITY_LEVEL9 ( 0x0009U ) /* Level 9 */
- #define portINT_PRIORITY_LEVEL10 ( 0x000AU ) /* Level 10 */
- #define portINT_PRIORITY_LEVEL11 ( 0x000BU ) /* Level 11 */
- #define portINT_PRIORITY_LEVEL12 ( 0x000CU ) /* Level 12 */
- #define portINT_PRIORITY_LEVEL13 ( 0x000DU ) /* Level 13 */
- #define portINT_PRIORITY_LEVEL14 ( 0x000EU ) /* Level 14 */
- #define portINT_PRIORITY_LOWEST ( 0x000FU ) /* Level 15 (lowest) */
+ #define portINT_PRIORITY_HIGHEST ( 0x0000U ) /* Level 0 (highest) */
+ #define portINT_PRIORITY_LEVEL1 ( 0x0001U ) /* Level 1 */
+ #define portINT_PRIORITY_LEVEL2 ( 0x0002U ) /* Level 2 */
+ #define portINT_PRIORITY_LEVEL3 ( 0x0003U ) /* Level 3 */
+ #define portINT_PRIORITY_LEVEL4 ( 0x0004U ) /* Level 4 */
+ #define portINT_PRIORITY_LEVEL5 ( 0x0005U ) /* Level 5 */
+ #define portINT_PRIORITY_LEVEL6 ( 0x0006U ) /* Level 6 */
+ #define portINT_PRIORITY_LEVEL7 ( 0x0007U ) /* Level 7 */
+ #define portINT_PRIORITY_LEVEL8 ( 0x0008U ) /* Level 8 */
+ #define portINT_PRIORITY_LEVEL9 ( 0x0009U ) /* Level 9 */
+ #define portINT_PRIORITY_LEVEL10 ( 0x000AU ) /* Level 10 */
+ #define portINT_PRIORITY_LEVEL11 ( 0x000BU ) /* Level 11 */
+ #define portINT_PRIORITY_LEVEL12 ( 0x000CU ) /* Level 12 */
+ #define portINT_PRIORITY_LEVEL13 ( 0x000DU ) /* Level 13 */
+ #define portINT_PRIORITY_LEVEL14 ( 0x000EU ) /* Level 14 */
+ #define portINT_PRIORITY_LOWEST ( 0x000FU ) /* Level 15 (lowest) */
/* Determine the descending of the stack from high address to address */
#define portSTACK_GROWTH ( -1 )
@@ -175,8 +175,10 @@
#define portGET_TASK_LOCK( xCoreID )
#define portRELEASE_TASK_LOCK( xCoreID )
#else
- extern void vPortRecursiveLockAcquire( BaseType_t xCoreID, BaseType_t xFromIsr );
- extern void vPortRecursiveLockRelease( BaseType_t xCoreID, BaseType_t xFromIsr );
+ extern void vPortRecursiveLockAcquire( BaseType_t xCoreID,
+ BaseType_t xFromIsr );
+ extern void vPortRecursiveLockRelease( BaseType_t xCoreID,
+ BaseType_t xFromIsr );
#define portGET_ISR_LOCK( xCoreID ) vPortRecursiveLockAcquire( ( xCoreID ), pdTRUE )
#define portRELEASE_ISR_LOCK( xCoreID ) vPortRecursiveLockRelease( ( xCoreID ), pdTRUE )
@@ -217,6 +219,6 @@
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( ( x ) )
#ifdef __cplusplus
-}
+ }
#endif
#endif /* PORTMACRO_H */