diff --git a/components/freertos/port/riscv/port.c b/components/freertos/port/riscv/port.c index 6895604c60..4e29cb6494 100644 --- a/components/freertos/port/riscv/port.c +++ b/components/freertos/port/riscv/port.c @@ -77,19 +77,23 @@ #include #include "FreeRTOS.h" #include "task.h" -#include "sdkconfig.h" #include "portmacro.h" -#include "riscv/interrupt.h" -#include "riscv/rvruntime-frames.h" + +#include "sdkconfig.h" + #include "soc/periph_defs.h" #include "soc/system_reg.h" -#include "soc/interrupt_reg.h" #include "hal/systimer_hal.h" #include "hal/systimer_ll.h" + +#include "riscv/rvruntime-frames.h" #include "riscv/riscv_interrupts.h" #include "riscv/interrupt.h" + #include "esp_system.h" #include "esp_intr_alloc.h" +#include "esp_private/crosscore_int.h" +#include "esp_attr.h" #include "esp_log.h" /** @@ -98,7 +102,7 @@ * to ensure interrupts don't inadvertently become unmasked before the scheduler starts. * As it is stored as part of the task context it will automatically be set to 0 when the first task is started. */ -static UBaseType_t uxCriticalNesting = 0; +static UBaseType_t uxCriticalNesting = 0; static UBaseType_t uxSavedInterruptState = 0; BaseType_t uxSchedulerRunning = 0; UBaseType_t uxInterruptNesting = 0; @@ -108,10 +112,8 @@ StackType_t *xIsrStackTop = &xIsrStack[0] + (configISR_STACK_SIZE & (~((portPOIN static const char *TAG = "cpu_start"; // [refactor-todo]: might be appropriate to change in the future, but -static void vPortSysTickHandler(void); +static void vPortSysTickHandler(void *arg); static void vPortSetupTimer(void); -static void vPortSetupSoftwareInterrupt(void); -static void vPortSoftwareInterrupt(void); static void prvTaskExitError(void); extern void esprv_intc_int_set_threshold(int); // FIXME, this function is in ROM only @@ -144,16 +146,9 @@ void vPortExitCritical(void) */ void vPortSetupTimer(void) { - /* register the interrupt handler */ - intr_handler_set(ETS_SYSTICK_INUM, (intr_handler_t)&vPortSysTickHandler, NULL); - - /* pass the timer interrupt through the interrupt matrix */ - intr_matrix_route(ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE, ETS_SYSTICK_INUM); - - /* enable the interrupt in the INTC */ - esprv_intc_int_enable(BIT(ETS_SYSTICK_INUM)); - esprv_intc_int_set_type(BIT(ETS_SYSTICK_INUM), INTR_TYPE_LEVEL); - esprv_intc_int_set_priority(ETS_SYSTICK_INUM, 1); + /* set system timer interrupt vector */ + esp_err_t err = esp_intr_alloc(ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE, ESP_INTR_FLAG_IRAM, vPortSysTickHandler, NULL, NULL); + assert(err == ESP_OK); /* configure the timer */ systimer_hal_init(); @@ -164,24 +159,6 @@ void vPortSetupTimer(void) systimer_hal_connect_alarm_counter(SYSTIMER_ALARM_0, SYSTIMER_COUNTER_1); } -/* setup software interrupt */ -void vPortSetupSoftwareInterrupt(void) -{ - /* register the interrupt handler, see interrupt.h */ - intr_handler_set(ETS_CPU_INTR0_INUM, (intr_handler_t)&vPortSoftwareInterrupt, NULL); - - /* pass the "FROM_CPU_0", a.k.a. cross-core interrupt, through the interrupt matrix */ - intr_matrix_route(ETS_FROM_CPU_INTR0_SOURCE, ETS_CPU_INTR0_INUM); - - /* enable the interrupt in the INTC */ - esprv_intc_int_enable(BIT(ETS_CPU_INTR0_INUM)); - esprv_intc_int_set_type(BIT(ETS_CPU_INTR0_INUM), INTR_TYPE_LEVEL); - esprv_intc_int_set_priority(ETS_CPU_INTR0_INUM, 1); - - // TODO ESP32-C3 IDF-2126, maybe can use interrupt allocation API for all of the above? unsure... - esp_intr_reserve(ETS_CPU_INTR0_INUM, xPortGetCoreID()); -} - void prvTaskExitError(void) { /* A function that implements a task must not exit or attempt to return to @@ -213,9 +190,6 @@ int vPortSetInterruptMask(void) return ret; } -/* - * See header file for description. - */ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters) { extern uint32_t __global_pointer$; @@ -232,11 +206,15 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC frame->a1 = 0x11111111; frame->a2 = 0x22222222; frame->a3 = 0x33333333; + + //TODO: IDF-2393 return (StackType_t *)frame; } -void vPortSysTickHandler(void) +IRAM_ATTR void vPortSysTickHandler(void *arg) { + (void)arg; + systimer_ll_clear_alarm_int(SYSTIMER_ALARM_0); if (!uxSchedulerRunning) { @@ -249,15 +227,18 @@ void vPortSysTickHandler(void) } BaseType_t xPortStartScheduler(void) -{ - vPortSetupTimer(); - vPortSetupSoftwareInterrupt(); +{ uxInterruptNesting = 0; uxCriticalNesting = 0; - uxSchedulerRunning = 0; /* this means first yield */ + uxSchedulerRunning = 0; + + vPortSetupTimer(); + esprv_intc_int_set_threshold(1); /* set global INTC masking level */ riscv_global_interrupts_enable(); + vPortYield(); + /*Should not get here*/ return pdFALSE; } @@ -265,20 +246,18 @@ BaseType_t xPortStartScheduler(void) void vPortEndScheduler(void) { /* very unlikely this function will be called, so just trap here */ - while (1) - ; -} - -void vPortSoftwareInterrupt(void) -{ - uxSchedulerRunning = 1; - REG_WRITE(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 0); + abort(); } void vPortYieldOtherCore(BaseType_t coreid) { - (void)coreid; - vPortYield(); + esp_crosscore_int_send_yield(coreid); +} + +void vPortYieldFromISR( void ) +{ + uxSchedulerRunning = 1; + xPortSwitchFlag = 1; } void vPortYield(void) @@ -286,9 +265,8 @@ void vPortYield(void) if (uxInterruptNesting) { vPortYieldFromISR(); } else { - xPortSwitchFlag = 1; - REG_WRITE(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 1); + esp_crosscore_int_send_yield(0); /* There are 3-4 instructions of latency between triggering the software interrupt and the CPU interrupt happening. Make sure it happened before we return, otherwise vTaskDelay() may return and execute 1-2 @@ -304,11 +282,6 @@ void vPortYield(void) } -void vPortYieldFromISR( void ) -{ - xPortSwitchFlag = 1; -} - void vPortSetStackWatchpoint(void *pxStackStart) { (void)pxStackStart; // TODO ESP32-C3 IDF-2207 @@ -328,24 +301,24 @@ BaseType_t IRAM_ATTR xPortInterruptedFromISRContext(void) void vPortCPUInitializeMutex(portMUX_TYPE *mux) { - (void)mux; + (void)mux; //TODO: IDF-2393 } void vPortCPUAcquireMutex(portMUX_TYPE *mux) { - (void)mux; + (void)mux; //TODO: IDF-2393 } bool vPortCPUAcquireMutexTimeout(portMUX_TYPE *mux, int timeout_cycles) { - (void)mux; + (void)mux; //TODO: IDF-2393 (void)timeout_cycles; return true; } void vPortCPUReleaseMutex(portMUX_TYPE *mux) { - (void)mux; + (void)mux; //TODO: IDF-2393 } void __attribute__((weak)) vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) diff --git a/components/freertos/port/riscv/portasm.S b/components/freertos/port/riscv/portasm.S index 8d19ba3467..04a5399a94 100644 --- a/components/freertos/port/riscv/portasm.S +++ b/components/freertos/port/riscv/portasm.S @@ -70,18 +70,18 @@ rtos_int_exit: beq t0,zero, rtos_exit_end /* update nesting interrupts counter */ - la t2, uxInterruptNesting - lw t3, 0x0(t2) + 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) + /* 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 + /* 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 diff --git a/components/hal/esp32c3/interrupt_descriptor_table.c b/components/hal/esp32c3/interrupt_descriptor_table.c index b4c8637b91..8c0837e195 100644 --- a/components/hal/esp32c3/interrupt_descriptor_table.c +++ b/components/hal/esp32c3/interrupt_descriptor_table.c @@ -16,9 +16,6 @@ #include "soc/soc_caps.h" #include "soc/soc.h" -// TODO ESP32-C3 IDF-2126 check this table is correct, some interrupts may be unnecessarily reserved or not reserved -// or marked as the wrong type - //This is basically a software-readable version of the interrupt usage table in include/soc/soc.h const int_desc_t interrupt_descriptor_table[32] = { { 1, INTTP_LEVEL, {INTDESC_RESVD } }, //0 diff --git a/components/riscv/vectors.S b/components/riscv/vectors.S index b55f4c12fe..081fb951d4 100644 --- a/components/riscv/vectors.S +++ b/components/riscv/vectors.S @@ -99,7 +99,6 @@ .global rtos_int_enter .global rtos_int_exit - .global uxInterruptNesting .global _global_interrupt_handler .section .exception_vectors.text