freertos/riscv: move freertos aware interrupt code from vectors to the freertos riscv port.

The riscv vectors.S in riscv component contains the trap vector, which is responsible to
defer interrupts and examine if a task context switch is needed, this change cleans up
this code by hiding all freertos details behind on two functions rtos_it_enter/exit and
their implementations are placed in freertos riscv port files.
pull/6416/head
Felipe Neves 2020-11-04 18:34:47 -03:00 zatwierdzone przez morris
rodzic e1d9abafa8
commit 810be86f21
3 zmienionych plików z 50 dodań i 57 usunięć

Wyświetl plik

@ -102,6 +102,7 @@ static UBaseType_t uxCriticalNesting = 0;
static UBaseType_t uxSavedInterruptState = 0;
BaseType_t uxSchedulerRunning = 0;
UBaseType_t uxInterruptNesting = 0;
BaseType_t xPortSwitchFlag = 0;
__attribute__((aligned(16))) static StackType_t xIsrStack[configISR_STACK_SIZE];
StackType_t *xIsrStackTop = &xIsrStack[0] + (configISR_STACK_SIZE & (~((portPOINTER_SIZE_TYPE)portBYTE_ALIGNMENT_MASK)));
@ -243,7 +244,7 @@ void vPortSysTickHandler(void)
}
if (xTaskIncrementTick() != pdFALSE) {
vTaskSwitchContext();
vPortYieldFromISR();
}
}
@ -251,6 +252,7 @@ BaseType_t xPortStartScheduler(void)
{
vPortSetupTimer();
vPortSetupSoftwareInterrupt();
uxInterruptNesting = 0;
uxCriticalNesting = 0;
uxSchedulerRunning = 0; /* this means first yield */
esprv_intc_int_set_threshold(1); /* set global INTC masking level */
@ -270,7 +272,6 @@ void vPortEndScheduler(void)
void vPortSoftwareInterrupt(void)
{
uxSchedulerRunning = 1;
vTaskSwitchContext();
REG_WRITE(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 0);
}
@ -285,6 +286,7 @@ void vPortYield(void)
if (uxInterruptNesting) {
vPortYieldFromISR();
} else {
xPortSwitchFlag = 1;
REG_WRITE(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 1);
/* There are 3-4 instructions of latency between triggering the software
@ -299,11 +301,12 @@ void vPortYield(void)
*/
while(uxSchedulerRunning && uxCriticalNesting == 0 && REG_READ(SYSTEM_CPU_INTR_FROM_CPU_0_REG) != 0) { }
}
}
void vPortYieldFromISR(void)
void vPortYieldFromISR( void )
{
vTaskSwitchContext();
xPortSwitchFlag = 1;
}
void vPortSetStackWatchpoint(void *pxStackStart)

Wyświetl plik

@ -36,15 +36,24 @@ rtos_int_enter:
mv t2, a0
/* scheduler not enabled, jump directly to ISR handler */
lw t0, uxSchedulerRunning
beq t0,zero, not_rtos_enter
lw t0, uxSchedulerRunning
beq t0,zero, rtos_enter_end
/* Sabe current TCB and load the ISR stack */
/* increments the ISR nesting count */
la t3, uxInterruptNesting
lw t4, 0x0(t3)
addi t5,t4,1
sw t5, 0x0(t3)
/* If reached here from another low-prio ISR, skip stack pushing to TCB */
bne t4,zero, rtos_enter_end
/* Save current TCB and load the ISR stack */
lw t0, pxCurrentTCB
sw t2, 0x0(t0)
lw sp, xIsrStackTop
not_rtos_enter:
rtos_enter_end:
mv ra, t1
ret
@ -56,10 +65,23 @@ not_rtos_enter:
.global rtos_int_exit
.type rtos_int_exit, @function
rtos_int_exit:
/* may skip RTOS aware interrupt since scheduler was not started */
lw t0, uxSchedulerRunning
beq t0,zero, not_rtos_exit
lw t0, uxSchedulerRunning
beq t0,zero, rtos_exit_end
/* update nesting interrupts counter */
la t2, uxInterruptNesting
lw t3, 0x0(t2)
/* Already zero, protect againts underflow */
beq t3, zero, isr_skip_decrement
addi t3,t3, -1
sw t3, 0x0(t2)
isr_skip_decrement:
/* may still have interrupts pending, skip section below and exit */
bne t3,zero,rtos_exit_end
/* Schedule the next task if a yield is pending */
la t0, xPortSwitchFlag
@ -83,5 +105,5 @@ no_switch:
lw a0, pxCurrentTCB
lw a0, 0x0(a0)
not_rtos_exit:
rtos_exit_end:
ret

Wyświetl plik

@ -97,11 +97,9 @@
csrw mepc, t0
.endm
.global vPortYieldFromISR
.global uxInterruptNesting
.global uxSchedulerRunning
.global xIsrStackTop
.global pxCurrentTCB
.global rtos_int_enter
.global rtos_int_exit
.global uxInterruptNesting
.global _global_interrupt_handler
.section .exception_vectors.text
@ -218,26 +216,12 @@ _interrupt_handler:
/* entry */
save_regs
save_mepc
/* Before doing anythig preserve the stack pointer */
/* It will be saved in current TCB, if needed */
mv a0, sp
call rtos_int_enter
/* scheduler not enabled, jump directly to ISR handler */
lw t0, uxSchedulerRunning
beq t0, zero, already_on_handler
/* increments the ISR nesting count */
la t0, uxInterruptNesting
lw t1, 0x0(t0)
addi t2,t1,1
sw t2, 0x0(t0)
/* If reached here from another low priority ISR, skip stack pushing to TCB */
bne t1,zero, already_on_handler
/* Otherwise, save current sp, and use the isr stack from here */
lw t0, pxCurrentTCB
sw sp, 0x0(t0)
lw sp, xIsrStackTop
already_on_handler:
/* Before dispatch c handler, restore interrupt to enable nested intr */
csrr s1, mcause
csrr s2, mstatus
@ -278,29 +262,13 @@ already_on_handler:
sw s3, 0(t0)
fence
/* may skip RTOS aware interrupt since scheduler was not started */
lw t1, uxSchedulerRunning
beq t1,zero, isr_exit
/* Yield to the next task is needed: */
mv a0, sp
call rtos_int_exit
/* update nesting interrupts counter */
la t0, uxInterruptNesting
lw t1, 0x0(t0)
/* The next (or current) stack pointer is returned in a0 */
mv sp, a0
/* Already zero, protect against underflow */
beq t1, zero, isr_skip_decrement
addi t1,t1, -1
sw t1, 0x0(t0)
isr_skip_decrement:
/* may still have interrupts pending, skip section below and exit */
bne t1,zero,isr_exit
/* handled all the ISRs and scheduled the next task, take its stack */
/* load on sp, then exit. */
lw sp, pxCurrentTCB
lw sp, 0x0(sp)
isr_exit:
/* restore the rest of the registers */
csrw mcause, s1
csrw mstatus, s2