From 530462ace487e52372ebb1ba43ed94dddf4f811d Mon Sep 17 00:00:00 2001 From: Trong Nguyen Date: Thu, 31 Oct 2024 19:42:25 +0700 Subject: [PATCH] Fix Interrupt depth comparison logic Fix parameter mismatch in portmacro.h file Add comment to explain assembly code --- portable/CCRH/F1Kx/README.md | 4 ++-- portable/CCRH/F1Kx/port.c | 4 ++-- portable/CCRH/F1Kx/portasm.s | 11 ++++++++--- portable/CCRH/F1Kx/portmacro.h | 8 ++++---- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/portable/CCRH/F1Kx/README.md b/portable/CCRH/F1Kx/README.md index 7583c67aff..4cb9f07b61 100644 --- a/portable/CCRH/F1Kx/README.md +++ b/portable/CCRH/F1Kx/README.md @@ -23,8 +23,8 @@ The test project can be found [here](https://github.com/FreeRTOS/FreeRTOS-Commun ## Note 1. Configure IPIR Interrupt: Ensure that the bit specifying the destination for binding (requesting) an interrupt is enabled (e.g: IBDxxx register of F1KH-D8) (1) 2. `Channel 0` and address `0xFFFEEC00` are used as default configuration for configIPIR_CHANNEL and configEXCLUSIVE_ADDRESS, in case of resource confliction other channel/address can be used. (2) - 3. The minimal stack size (configMINIMAL_STACK_SIZE) must be included the reserved memory for nested interrupt. This formula can be referred: `(task_context_size) * (1 + 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. + 3. 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). 4. `configTIMER_PRESCALE`: This value is required in order to correctly configure clock for `CPUCLK_L`. Refer to Hardware Manual at `Table 44.22` for `option byte`: If the user sets the option byte `CKDIVMD to 1`, then `configTIMER_PRESCALE = 4`. Otherwise, if `CKDIVMD is set to 0`, then `configTIMER_PRESCALE = 2`. (1) This is applicable for F1KH-D8 with SMP only. diff --git a/portable/CCRH/F1Kx/port.c b/portable/CCRH/F1Kx/port.c index e3d71929d8..0e6116527d 100644 --- a/portable/CCRH/F1Kx/port.c +++ b/portable/CCRH/F1Kx/port.c @@ -171,7 +171,7 @@ #define configSETUP_TICK_INTERRUPT() prvSetupTimerInterrupt() #endif /* configSETUP_TICK_INTERRUPT */ -#ifndef configMAX_INT_NESTING +#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 @@ -225,7 +225,7 @@ volatile BaseType_t xPortScheduleStatus[ configNUMBER_OF_CORES ] = { 0 }; * It is necessary to control maximum stack depth. */ volatile UBaseType_t uxInterruptNesting[ configNUMBER_OF_CORES ] = { 0 }; -volatile const UBaseType_t uxPortMaxInterruptDepth = configMAX_INT_NESTING - 1; +volatile const UBaseType_t uxPortMaxInterruptDepth = configMAX_INT_NESTING; /* 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 diff --git a/portable/CCRH/F1Kx/portasm.s b/portable/CCRH/F1Kx/portasm.s index 29395dbd94..ff8e7ee31f 100644 --- a/portable/CCRH/F1Kx/portasm.s +++ b/portable/CCRH/F1Kx/portasm.s @@ -84,6 +84,8 @@ portSAVE_CONTEXT .macro stsr FPEPC, r19 pushsp r18, r19 + ; Save EIPSW register to stack + ; Due to the syntax of the pushsp instruction, using r14 as dummy value pushsp r14, r15 ; Get current TCB, the return value is stored in r10 (CCRH compiler) @@ -103,6 +105,8 @@ portRESTORE_CONTEXT .macro ; Restore FPU registers if FPU is enabled mov FPU_MSK, r19 + ; Restore EIPSW register to check FPU + ; Due to the syntax of the popsp instruction, using r14 as dummy value popsp r14, r15 tst r15, r19 ; Jump over next 3 instructions: stsr (4 bytes)*2 + popsp (4 bytes) @@ -269,9 +273,10 @@ _vIrq_Handler: ; Do not enable interrupt for nesting. Stackover flow may occurs if the ; depth of nesting interrupt is exceeded. - mov #_uxPortMaxInterruptDepth, r15 - cmp r16, r15 - be 4 ; Jump over ei instruction + mov #_uxPortMaxInterruptDepth, r19 + ld.w 0[r19], r15 + cmp r15, r16 + bge 4 ; Jump over ei instruction ei jarl _vCommonISRHandler, lp di diff --git a/portable/CCRH/F1Kx/portmacro.h b/portable/CCRH/F1Kx/portmacro.h index e2b41f2640..09f9f46145 100644 --- a/portable/CCRH/F1Kx/portmacro.h +++ b/portable/CCRH/F1Kx/portmacro.h @@ -111,11 +111,11 @@ /* Scheduler utilities */ /* Called at the end of an ISR that can cause a context switch */ - extern void vPortSetSwitch( BaseType_t vPortSetSwitch ); + extern void vPortSetSwitch( BaseType_t xSwitchRequired ); - #define portEND_SWITCHING_ISR( xSwitchRequired ) vPortSetSwitch( vPortSetSwitch ) + #define portEND_SWITCHING_ISR( x ) vPortSetSwitch( x ) - #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) + #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /* Use to transfer control from one task to perform other tasks of * higher priority */ @@ -131,7 +131,7 @@ #define coreid xPortGET_CORE_ID() /* Request the core ID x to yield. */ - extern void vPortYieldCore( unsigned int coreID ); + extern void vPortYieldCore( uint32_t coreID ); #define portYIELD_CORE( x ) vPortYieldCore( x )