mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Enhancements and Bug Fixes for F1Kx Port (#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
This commit is contained in:
parent
f0d79459d6
commit
d0d55f3031
|
@ -23,8 +23,8 @@ The test project can be found [here](https://github.com/FreeRTOS/FreeRTOS-Commun
|
||||||
## Note
|
## 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)
|
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)
|
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`
|
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.
|
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`.
|
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.
|
(1) This is applicable for F1KH-D8 with SMP only.
|
||||||
|
|
|
@ -171,7 +171,7 @@
|
||||||
#define configSETUP_TICK_INTERRUPT() prvSetupTimerInterrupt()
|
#define configSETUP_TICK_INTERRUPT() prvSetupTimerInterrupt()
|
||||||
#endif /* configSETUP_TICK_INTERRUPT */
|
#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
|
/* Set the default value for depth of nested interrupt. In theory, the
|
||||||
* microcontroller have mechanism to limit number of nested level of interrupt
|
* 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.
|
* It is necessary to control maximum stack depth.
|
||||||
*/
|
*/
|
||||||
volatile UBaseType_t uxInterruptNesting[ configNUMBER_OF_CORES ] = { 0 };
|
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
|
/* 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
|
* only if this count is decreased to 0, the lock is separated for task
|
||||||
|
|
|
@ -84,6 +84,10 @@ portSAVE_CONTEXT .macro
|
||||||
stsr FPEPC, r19
|
stsr FPEPC, r19
|
||||||
pushsp r18, 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)
|
; Get current TCB, the return value is stored in r10 (CCRH compiler)
|
||||||
jarl _pvPortGetCurrentTCB, lp
|
jarl _pvPortGetCurrentTCB, lp
|
||||||
st.w sp, 0[r10]
|
st.w sp, 0[r10]
|
||||||
|
@ -101,14 +105,15 @@ portRESTORE_CONTEXT .macro
|
||||||
|
|
||||||
; Restore FPU registers if FPU is enabled
|
; Restore FPU registers if FPU is enabled
|
||||||
mov FPU_MSK, r19
|
mov FPU_MSK, r19
|
||||||
stsr PSW, r18
|
; Restore EIPSW register to check FPU
|
||||||
tst r18, r19
|
; 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)
|
; Jump over next 3 instructions: stsr (4 bytes)*2 + popsp (4 bytes)
|
||||||
bz 12
|
bz 12
|
||||||
popsp r18, r19
|
popsp r18, r19
|
||||||
ldsr r18, FPEPC
|
ldsr r19, FPEPC
|
||||||
ldsr r19, FPSR
|
ldsr r18, FPSR
|
||||||
|
|
||||||
;Restore general-purpose registers and EIPSW, EIPC, EIIC, CTPSW, CTPC
|
;Restore general-purpose registers and EIPSW, EIPC, EIIC, CTPSW, CTPC
|
||||||
popsp r15, r19
|
popsp r15, r19
|
||||||
|
@ -146,14 +151,15 @@ SAVE_REGISTER .macro
|
||||||
mov ep, r15
|
mov ep, r15
|
||||||
stsr CTPSW, r14
|
stsr CTPSW, r14
|
||||||
stsr CTPC, r13
|
stsr CTPC, r13
|
||||||
pushsp r13, r19
|
pushsp r13, r18
|
||||||
|
|
||||||
mov FPU_MSK, r16
|
mov FPU_MSK, r16
|
||||||
tst r16, r19
|
tst r16, r19
|
||||||
bz 12
|
bz 8
|
||||||
stsr FPSR, r18
|
stsr FPSR, r17
|
||||||
stsr FPEPC, r19
|
stsr FPEPC, r18
|
||||||
pushsp r18, r19
|
|
||||||
|
pushsp r17, r19
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
|
@ -161,15 +167,14 @@ SAVE_REGISTER .macro
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
RESTORE_REGISTER .macro
|
RESTORE_REGISTER .macro
|
||||||
|
|
||||||
mov FPU_MSK, r16
|
mov FPU_MSK, r15
|
||||||
stsr PSW, r18
|
popsp r17, r19
|
||||||
tst r18, r19
|
tst r19, r15
|
||||||
bz 12
|
bz 8
|
||||||
popsp r18, r19
|
|
||||||
ldsr r18, FPEPC
|
ldsr r18, FPEPC
|
||||||
ldsr r19, FPSR
|
ldsr r17, FPSR
|
||||||
|
|
||||||
popsp r13, r19
|
popsp r13, r18
|
||||||
ldsr r13, CTPC
|
ldsr r13, CTPC
|
||||||
ldsr r14, CTPSW
|
ldsr r14, CTPSW
|
||||||
mov r15, ep
|
mov r15, ep
|
||||||
|
@ -268,9 +273,10 @@ _vIrq_Handler:
|
||||||
|
|
||||||
; Do not enable interrupt for nesting. Stackover flow may occurs if the
|
; Do not enable interrupt for nesting. Stackover flow may occurs if the
|
||||||
; depth of nesting interrupt is exceeded.
|
; depth of nesting interrupt is exceeded.
|
||||||
mov #_uxPortMaxInterruptDepth, r15
|
mov #_uxPortMaxInterruptDepth, r19
|
||||||
cmp r16, r15
|
ld.w 0[r19], r15
|
||||||
be 4 ; Jump over ei instruction
|
cmp r15, r16
|
||||||
|
bge 4 ; Jump over ei instruction
|
||||||
ei
|
ei
|
||||||
jarl _vCommonISRHandler, lp
|
jarl _vCommonISRHandler, lp
|
||||||
di
|
di
|
||||||
|
|
|
@ -111,9 +111,9 @@
|
||||||
/* Scheduler utilities */
|
/* Scheduler utilities */
|
||||||
|
|
||||||
/* Called at the end of an ISR that can cause a context switch */
|
/* 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 )
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@
|
||||||
#define coreid xPortGET_CORE_ID()
|
#define coreid xPortGET_CORE_ID()
|
||||||
|
|
||||||
/* Request the core ID x to yield. */
|
/* 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 )
|
#define portYIELD_CORE( x ) vPortYieldCore( x )
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue