Skip to content

Commit d0d55f3

Browse files
authored
Enhancements and Bug Fixes for F1Kx Port (FreeRTOS#1169)
Fix FPU stack order issue and Improve FPU checking flow Fix Interrupt depth comparison logic Fix parameter mismatch in portmacro.h file Add comment to explain assembly code
1 parent f0d7945 commit d0d55f3

File tree

4 files changed

+35
-29
lines changed

4 files changed

+35
-29
lines changed

portable/CCRH/F1Kx/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ The test project can be found [here](https://github.com/FreeRTOS/FreeRTOS-Commun
2323
## Note
2424
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)
2525
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)
26-
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`
27-
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.
26+
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`
27+
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).
2828
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`.
2929

3030
(1) This is applicable for F1KH-D8 with SMP only.

portable/CCRH/F1Kx/port.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@
171171
#define configSETUP_TICK_INTERRUPT() prvSetupTimerInterrupt()
172172
#endif /* configSETUP_TICK_INTERRUPT */
173173

174-
#ifndef configMAX_INT_NESTING
174+
#if ( !defined( configMAX_INT_NESTING ) || ( configMAX_INT_NESTING == 0 ) )
175175

176176
/* Set the default value for depth of nested interrupt. In theory, the
177177
* microcontroller have mechanism to limit number of nested level of interrupt
@@ -225,7 +225,7 @@ volatile BaseType_t xPortScheduleStatus[ configNUMBER_OF_CORES ] = { 0 };
225225
* It is necessary to control maximum stack depth.
226226
*/
227227
volatile UBaseType_t uxInterruptNesting[ configNUMBER_OF_CORES ] = { 0 };
228-
volatile const UBaseType_t uxPortMaxInterruptDepth = configMAX_INT_NESTING - 1;
228+
volatile const UBaseType_t uxPortMaxInterruptDepth = configMAX_INT_NESTING;
229229

230230
/* Count number of nested locks by same cores. The lock is completely released
231231
* only if this count is decreased to 0, the lock is separated for task

portable/CCRH/F1Kx/portasm.s

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ portSAVE_CONTEXT .macro
8484
stsr FPEPC, r19
8585
pushsp r18, r19
8686

87+
; Save EIPSW register to stack
88+
; Due to the syntax of the pushsp instruction, using r14 as dummy value
89+
pushsp r14, r15
90+
8791
; Get current TCB, the return value is stored in r10 (CCRH compiler)
8892
jarl _pvPortGetCurrentTCB, lp
8993
st.w sp, 0[r10]
@@ -101,14 +105,15 @@ portRESTORE_CONTEXT .macro
101105

102106
; Restore FPU registers if FPU is enabled
103107
mov FPU_MSK, r19
104-
stsr PSW, r18
105-
tst r18, r19
106-
107-
; Jump over next 3 instructions: stsr (4 bytes)*2 + popsp (4 bytes)
108+
; Restore EIPSW register to check FPU
109+
; Due to the syntax of the popsp instruction, using r14 as dummy value
110+
popsp r14, r15
111+
tst r15, r19
112+
; Jump over next 3 instructions: stsr (4 bytes)*2 + popsp (4 bytes)
108113
bz 12
109114
popsp r18, r19
110-
ldsr r18, FPEPC
111-
ldsr r19, FPSR
115+
ldsr r19, FPEPC
116+
ldsr r18, FPSR
112117

113118
;Restore general-purpose registers and EIPSW, EIPC, EIIC, CTPSW, CTPC
114119
popsp r15, r19
@@ -146,30 +151,30 @@ SAVE_REGISTER .macro
146151
mov ep, r15
147152
stsr CTPSW, r14
148153
stsr CTPC, r13
149-
pushsp r13, r19
154+
pushsp r13, r18
150155

151156
mov FPU_MSK, r16
152157
tst r16, r19
153-
bz 12
154-
stsr FPSR, r18
155-
stsr FPEPC, r19
156-
pushsp r18, r19
158+
bz 8
159+
stsr FPSR, r17
160+
stsr FPEPC, r18
161+
162+
pushsp r17, r19
157163

158164
.endm
159165
;------------------------------------------------------------------------------
160166
; Restore used registers
161167
;------------------------------------------------------------------------------
162168
RESTORE_REGISTER .macro
163169

164-
mov FPU_MSK, r16
165-
stsr PSW, r18
166-
tst r18, r19
167-
bz 12
168-
popsp r18, r19
170+
mov FPU_MSK, r15
171+
popsp r17, r19
172+
tst r19, r15
173+
bz 8
169174
ldsr r18, FPEPC
170-
ldsr r19, FPSR
175+
ldsr r17, FPSR
171176

172-
popsp r13, r19
177+
popsp r13, r18
173178
ldsr r13, CTPC
174179
ldsr r14, CTPSW
175180
mov r15, ep
@@ -268,9 +273,10 @@ _vIrq_Handler:
268273

269274
; Do not enable interrupt for nesting. Stackover flow may occurs if the
270275
; depth of nesting interrupt is exceeded.
271-
mov #_uxPortMaxInterruptDepth, r15
272-
cmp r16, r15
273-
be 4 ; Jump over ei instruction
276+
mov #_uxPortMaxInterruptDepth, r19
277+
ld.w 0[r19], r15
278+
cmp r15, r16
279+
bge 4 ; Jump over ei instruction
274280
ei
275281
jarl _vCommonISRHandler, lp
276282
di

portable/CCRH/F1Kx/portmacro.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,11 @@
111111
/* Scheduler utilities */
112112

113113
/* Called at the end of an ISR that can cause a context switch */
114-
extern void vPortSetSwitch( BaseType_t vPortSetSwitch );
114+
extern void vPortSetSwitch( BaseType_t xSwitchRequired );
115115

116-
#define portEND_SWITCHING_ISR( xSwitchRequired ) vPortSetSwitch( vPortSetSwitch )
116+
#define portEND_SWITCHING_ISR( x ) vPortSetSwitch( x )
117117

118-
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
118+
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
119119

120120
/* Use to transfer control from one task to perform other tasks of
121121
* higher priority */
@@ -131,7 +131,7 @@
131131
#define coreid xPortGET_CORE_ID()
132132

133133
/* Request the core ID x to yield. */
134-
extern void vPortYieldCore( unsigned int coreID );
134+
extern void vPortYieldCore( uint32_t coreID );
135135

136136
#define portYIELD_CORE( x ) vPortYieldCore( x )
137137

0 commit comments

Comments
 (0)