freertos: riscv port now uses interrupt allocator and crosscore interrupt

pull/6416/head
Felipe Neves 2020-11-13 16:03:50 -03:00 zatwierdzone przez morris
rodzic 09bc1580be
commit f4781d3b1d
4 zmienionych plików z 46 dodań i 77 usunięć

Wyświetl plik

@ -77,19 +77,23 @@
#include <string.h>
#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)

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -99,7 +99,6 @@
.global rtos_int_enter
.global rtos_int_exit
.global uxInterruptNesting
.global _global_interrupt_handler
.section .exception_vectors.text