feat(freertos): base support on p4

This commit is contained in:
Armando
2023-07-18 16:21:15 +08:00
committed by Armando (Dou Yiwen)
parent e11b154c99
commit 48ee1ba36e
7 changed files with 279 additions and 11 deletions

View File

@@ -3,7 +3,7 @@
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
* SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD
*/ */
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
@@ -160,6 +160,8 @@ BaseType_t xPortInterruptedFromISRContext(void);
* @note [refactor-todo] Refactor critical section API so that this is no longer required * @note [refactor-todo] Refactor critical section API so that this is no longer required
* ------------------------------------------------------ */ * ------------------------------------------------------ */
//TODO: IDF-7566
#if !CONFIG_IDF_TARGET_ESP32P4
/** /**
* @brief Spinlock object * @brief Spinlock object
* Owner: * Owner:
@@ -178,6 +180,11 @@ typedef struct {
uint32_t owner; uint32_t owner;
uint32_t count; uint32_t count;
} portMUX_TYPE; } portMUX_TYPE;
#else
typedef spinlock_t portMUX_TYPE; /**< Spinlock type used by FreeRTOS critical sections */
#endif
/**< Spinlock initializer */ /**< Spinlock initializer */
#define portMUX_INITIALIZER_UNLOCKED { \ #define portMUX_INITIALIZER_UNLOCKED { \
.owner = portMUX_FREE_VAL, \ .owner = portMUX_FREE_VAL, \
@@ -199,7 +206,12 @@ typedef struct {
* - Simply disable interrupts * - Simply disable interrupts
* - Can be nested * - Can be nested
*/ */
//TODO: IDF-7566
#if !CONFIG_IDF_TARGET_ESP32P4
void vPortEnterCritical(void); void vPortEnterCritical(void);
#else
void vPortEnterCritical(portMUX_TYPE *mux);
#endif
/** /**
* @brief Exit a critical section * @brief Exit a critical section
@@ -207,7 +219,12 @@ void vPortEnterCritical(void);
* - Reenables interrupts * - Reenables interrupts
* - Can be nested * - Can be nested
*/ */
//TODO: IDF-7566
#if !CONFIG_IDF_TARGET_ESP32P4
void vPortExitCritical(void); void vPortExitCritical(void);
#else
void vPortExitCritical(portMUX_TYPE *mux);
#endif
// ---------------------- Yielding ------------------------- // ---------------------- Yielding -------------------------
@@ -320,6 +337,8 @@ FORCE_INLINE_ATTR BaseType_t xPortGetCoreID(void)
// ------------------ Critical Sections -------------------- // ------------------ Critical Sections --------------------
//TODO: IDF-7566
#if !CONFIG_IDF_TARGET_ESP32P4
#define portENTER_CRITICAL(mux) {(void)mux; vPortEnterCritical();} #define portENTER_CRITICAL(mux) {(void)mux; vPortEnterCritical();}
#define portEXIT_CRITICAL(mux) {(void)mux; vPortExitCritical();} #define portEXIT_CRITICAL(mux) {(void)mux; vPortExitCritical();}
#define portTRY_ENTER_CRITICAL(mux, timeout) ({ \ #define portTRY_ENTER_CRITICAL(mux, timeout) ({ \
@@ -328,6 +347,17 @@ FORCE_INLINE_ATTR BaseType_t xPortGetCoreID(void)
BaseType_t ret = pdPASS; \ BaseType_t ret = pdPASS; \
ret; \ ret; \
}) })
#else
#define portENTER_CRITICAL(mux) {vPortEnterCritical(mux);}
#define portEXIT_CRITICAL(mux) {vPortExitCritical(mux);}
#define portTRY_ENTER_CRITICAL(mux, timeout) ({ \
(void)timeout; \
vPortEnterCritical(mux); \
BaseType_t ret = pdPASS; \
ret; \
})
#endif
//In single-core RISC-V, we can use the same critical section API //In single-core RISC-V, we can use the same critical section API
#define portENTER_CRITICAL_ISR(mux) portENTER_CRITICAL(mux) #define portENTER_CRITICAL_ISR(mux) portENTER_CRITICAL(mux)
#define portEXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL(mux) #define portEXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL(mux)
@@ -350,6 +380,10 @@ FORCE_INLINE_ATTR BaseType_t xPortGetCoreID(void)
}) })
#define portTRY_ENTER_CRITICAL_SAFE(mux, timeout) portENTER_CRITICAL_SAFE(mux, timeout) #define portTRY_ENTER_CRITICAL_SAFE(mux, timeout) portENTER_CRITICAL_SAFE(mux, timeout)
//TODO: IDF-7566
#if CONFIG_IDF_TARGET_ESP32P4
#define portCHECK_IF_IN_ISR() xPortInIsrContext()
#endif
// ---------------------- Yielding ------------------------- // ---------------------- Yielding -------------------------
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
@@ -428,7 +462,13 @@ extern void vPortCleanUpTCB ( void *pxTCB );
FORCE_INLINE_ATTR bool xPortCanYield(void) FORCE_INLINE_ATTR bool xPortCanYield(void)
{ {
//TODO: IDF-7566
#if SOC_INT_CLIC_SUPPORTED
uint32_t threshold = REG_READ(INTERRUPT_CORE0_CPU_INT_THRESH_REG + 0x10000 * xPortGetCoreID());
threshold = threshold >> (24 + (8 - NLBITS));
#else
uint32_t threshold = REG_READ(INTERRUPT_CORE0_CPU_INT_THRESH_REG); uint32_t threshold = REG_READ(INTERRUPT_CORE0_CPU_INT_THRESH_REG);
#endif
/* when enter critical code, FreeRTOS will mask threshold to RVHAL_EXCM_LEVEL /* when enter critical code, FreeRTOS will mask threshold to RVHAL_EXCM_LEVEL
* and exit critical code, will recover threshold value (1). so threshold <= 1 * and exit critical code, will recover threshold value (1). so threshold <= 1
* means not in critical code * means not in critical code

View File

@@ -3,7 +3,7 @@
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
* SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD
*/ */
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
@@ -56,6 +56,10 @@
#include "portmacro.h" #include "portmacro.h"
#include "port_systick.h" #include "port_systick.h"
#include "esp_memory_utils.h" #include "esp_memory_utils.h"
#if CONFIG_IDF_TARGET_ESP32P4
//TODO: IDF-7566
#include "soc/hp_system_reg.h"
#endif
_Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16"); _Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16");
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD #if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
@@ -74,6 +78,8 @@ _Static_assert(offsetof( StaticTask_t, pxDummy8 ) == PORT_OFFSET_PX_END_OF_STACK
* *
* ------------------------------------------------------------------------------------------------------------------ */ * ------------------------------------------------------------------------------------------------------------------ */
//TODO: IDF-7566
#if !CONFIG_IDF_TARGET_ESP32P4
/** /**
* @brief A variable is used to keep track of the critical section nesting. * @brief A variable is used to keep track of the critical section nesting.
* @note This variable has to be stored as part of the task context and must be initialized to a non zero value * @note This variable has to be stored as part of the task context and must be initialized to a non zero value
@@ -88,6 +94,25 @@ BaseType_t xPortSwitchFlag = 0;
__attribute__((aligned(16))) StackType_t xIsrStack[configISR_STACK_SIZE]; __attribute__((aligned(16))) StackType_t xIsrStack[configISR_STACK_SIZE];
StackType_t *xIsrStackTop = &xIsrStack[0] + (configISR_STACK_SIZE & (~((portPOINTER_SIZE_TYPE)portBYTE_ALIGNMENT_MASK))); StackType_t *xIsrStackTop = &xIsrStack[0] + (configISR_STACK_SIZE & (~((portPOINTER_SIZE_TYPE)portBYTE_ALIGNMENT_MASK)));
#else
/* uxCriticalNesting will be increased by 1 each time one processor is entering a critical section
* and will be decreased by 1 each time one processor is exiting a critical section
*/
volatile UBaseType_t uxCriticalNesting[portNUM_PROCESSORS] = {0};
volatile UBaseType_t uxSavedInterruptState[portNUM_PROCESSORS] = {0};
volatile BaseType_t uxSchedulerRunning[portNUM_PROCESSORS] = {0};
volatile UBaseType_t uxInterruptNesting[portNUM_PROCESSORS] = {0};
volatile BaseType_t xPortSwitchFlag[portNUM_PROCESSORS] = {0};
/* core0 interrupt stack space */
__attribute__((aligned(16))) static StackType_t xIsrStack[configISR_STACK_SIZE];
/* core1 interrupt stack space */
__attribute__((aligned(16))) static StackType_t xIsrStack1[configISR_STACK_SIZE];
/* core0 interrupt stack top, passed to sp */
StackType_t *xIsrStackTop = &xIsrStack[0] + (configISR_STACK_SIZE & (~((portPOINTER_SIZE_TYPE)portBYTE_ALIGNMENT_MASK)));
/* core1 interrupt stack top, passed to sp */
StackType_t *xIsrStackTop1 = &xIsrStack1[0] + (configISR_STACK_SIZE & (~((portPOINTER_SIZE_TYPE)portBYTE_ALIGNMENT_MASK)));
#endif
/* ------------------------------------------------ FreeRTOS Portable -------------------------------------------------- /* ------------------------------------------------ FreeRTOS Portable --------------------------------------------------
@@ -97,11 +122,19 @@ StackType_t *xIsrStackTop = &xIsrStack[0] + (configISR_STACK_SIZE & (~((portPOIN
// ----------------- Scheduler Start/End ------------------- // ----------------- Scheduler Start/End -------------------
//TODO: IDF-7566
BaseType_t xPortStartScheduler(void) BaseType_t xPortStartScheduler(void)
{ {
#if !CONFIG_IDF_TARGET_ESP32P4
uxInterruptNesting = 0; uxInterruptNesting = 0;
uxCriticalNesting = 0; uxCriticalNesting = 0;
uxSchedulerRunning = 0; uxSchedulerRunning = 0;
#else
BaseType_t coreID = xPortGetCoreID();
uxInterruptNesting[coreID] = 0;
uxCriticalNesting[coreID] = 0;
uxSchedulerRunning[coreID] = 0;
#endif
/* Setup the hardware to generate the tick. */ /* Setup the hardware to generate the tick. */
vPortSetupTimer(); vPortSetupTimer();
@@ -312,15 +345,26 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC
// --------------------- Interrupts ------------------------ // --------------------- Interrupts ------------------------
//TODO: IDF-7566
BaseType_t xPortInIsrContext(void) BaseType_t xPortInIsrContext(void)
{ {
#if !CONFIG_IDF_TARGET_ESP32P4
return uxInterruptNesting; return uxInterruptNesting;
#else
BaseType_t coreID = xPortGetCoreID();
return uxInterruptNesting[coreID];
#endif
} }
BaseType_t IRAM_ATTR xPortInterruptedFromISRContext(void) BaseType_t IRAM_ATTR xPortInterruptedFromISRContext(void)
{ {
/* For single core, this can be the same as xPortInIsrContext() because reading it is atomic */ /* For single core, this can be the same as xPortInIsrContext() because reading it is atomic */
#if !CONFIG_IDF_TARGET_ESP32P4
return uxInterruptNesting; return uxInterruptNesting;
#else
BaseType_t coreID = xPortGetCoreID();
return uxInterruptNesting[coreID];
#endif
} }
// ---------------------- Spinlocks ------------------------ // ---------------------- Spinlocks ------------------------
@@ -329,6 +373,8 @@ BaseType_t IRAM_ATTR xPortInterruptedFromISRContext(void)
// ------------------ Critical Sections -------------------- // ------------------ Critical Sections --------------------
//TODO: IDF-7566
#if !CONFIG_IDF_TARGET_ESP32P4
void vPortEnterCritical(void) void vPortEnterCritical(void)
{ {
BaseType_t state = portSET_INTERRUPT_MASK_FROM_ISR(); BaseType_t state = portSET_INTERRUPT_MASK_FROM_ISR();
@@ -349,15 +395,52 @@ void vPortExitCritical(void)
} }
} }
#else
void vPortEnterCritical(portMUX_TYPE *mux)
{
BaseType_t coreID = xPortGetCoreID();
BaseType_t state = portSET_INTERRUPT_MASK_FROM_ISR();
spinlock_acquire((spinlock_t *)mux, SPINLOCK_WAIT_FOREVER);
uxCriticalNesting[coreID]++;
if (uxCriticalNesting[coreID] == 1) {
uxSavedInterruptState[coreID] = state;
}
}
void vPortExitCritical(portMUX_TYPE *mux)
{
spinlock_release((spinlock_t *)mux);
BaseType_t coreID = xPortGetCoreID();
if (uxCriticalNesting[coreID] > 0) {
uxCriticalNesting[coreID]--;
if (uxCriticalNesting[coreID] == 0) {
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptState[coreID]);
}
}
}
#endif
// ---------------------- Yielding ------------------------- // ---------------------- Yielding -------------------------
//TODO: IDF-7566
int vPortSetInterruptMask(void) int vPortSetInterruptMask(void)
{ {
int ret; int ret;
unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE); unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
ret = REG_READ(INTERRUPT_CORE0_CPU_INT_THRESH_REG); ret = REG_READ(INTERRUPT_CORE0_CPU_INT_THRESH_REG);
#if !CONFIG_IDF_TARGET_ESP32P4
REG_WRITE(INTERRUPT_CORE0_CPU_INT_THRESH_REG, RVHAL_EXCM_LEVEL); REG_WRITE(INTERRUPT_CORE0_CPU_INT_THRESH_REG, RVHAL_EXCM_LEVEL);
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE); RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
#else
#define RVHAL_EXCM_THRESHOLD_VALUE (((RVHAL_EXCM_LEVEL << (8 - NLBITS)) | 0x1f) << CLIC_CPU_INT_THRESH_S)
REG_WRITE(INTERRUPT_CORE0_CPU_INT_THRESH_REG, RVHAL_EXCM_THRESHOLD_VALUE);
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
#endif
/** /**
* In theory, this function should not return immediately as there is a * In theory, this function should not return immediately as there is a
* delay between the moment we mask the interrupt threshold register and * delay between the moment we mask the interrupt threshold register and
@@ -395,6 +478,8 @@ void vPortClearInterruptMask(int mask)
asm volatile ( "nop" ); asm volatile ( "nop" );
} }
//TODO: IDF-7566
#if !CONFIG_IDF_TARGET_ESP32P4
void vPortYield(void) void vPortYield(void)
{ {
if (uxInterruptNesting) { if (uxInterruptNesting) {
@@ -423,6 +508,37 @@ void vPortYieldFromISR( void )
xPortSwitchFlag = 1; xPortSwitchFlag = 1;
} }
#else
void vPortYield(void)
{
BaseType_t coreID = xPortGetCoreID();
if (uxInterruptNesting[coreID]) {
vPortYieldFromISR();
} else {
esp_crosscore_int_send_yield(coreID);
/* 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
instructions before the delay actually happens.
(We could use the WFI instruction here, but there is a chance that
the interrupt will happen while evaluating the other two conditions
for an instant yield, and if that happens then the WFI would be
waiting for the next interrupt to occur...)
*/
while (uxSchedulerRunning[coreID] && uxCriticalNesting[coreID] == 0 && REG_READ(HP_SYSTEM_CPU_INT_FROM_CPU_0_REG + 4*coreID) != 0) {}
}
}
void vPortYieldFromISR( void )
{
traceISR_EXIT_TO_SCHEDULER();
BaseType_t coreID = xPortGetCoreID();
uxSchedulerRunning[coreID] = 1;
xPortSwitchFlag[coreID] = 1;
}
#endif
void vPortYieldOtherCore(BaseType_t coreid) void vPortYieldOtherCore(BaseType_t coreid)
{ {
esp_crosscore_int_send_yield(coreid); esp_crosscore_int_send_yield(coreid);

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -12,6 +12,10 @@
.global uxInterruptNesting .global uxInterruptNesting
.global uxSchedulerRunning .global uxSchedulerRunning
.global xIsrStackTop .global xIsrStackTop
#if CONFIG_IDF_TARGET_ESP32P4
//TODO: IDF-7566
.global xIsrStackTop1
#endif
.global pxCurrentTCB .global pxCurrentTCB
.global vTaskSwitchContext .global vTaskSwitchContext
.global xPortSwitchFlag .global xPortSwitchFlag
@@ -35,18 +39,40 @@
.global rtos_int_enter .global rtos_int_enter
.type rtos_int_enter, @function .type rtos_int_enter, @function
rtos_int_enter: rtos_int_enter:
#if CONFIG_IDF_TARGET_ESP32P4
/* needs jira for p4 */
/* preserve the return address */
mv t1, ra
mv t2, a0
#endif
//TODO: IDF-7566
#if !CONFIG_IDF_TARGET_ESP32P4
/* scheduler not enabled, jump directly to ISR handler */ /* scheduler not enabled, jump directly to ISR handler */
lw t0, uxSchedulerRunning lw t0, uxSchedulerRunning
beq t0,zero, rtos_enter_end beq t0,zero, rtos_enter_end
#else
/* scheduler not enabled, jump directly to ISR handler */
csrr t6, mhartid /* t6 = coreID */
slli t6, t6, 2 /* t6 = coreID * 4 */
la t0, uxSchedulerRunning /* t0 = &uxSchedulerRunning */
add t0, t0, t6 /* t0 = &uxSchedulerRunning[coreID] */
lw t0, (t0) /* t0 = uxSchedulerRunning[coreID] */
beq t0,zero, rtos_enter_end
#endif
/* increments the ISR nesting count */ /* increments the ISR nesting count */
la t3, uxInterruptNesting la t3, uxInterruptNesting
lw t4, 0x0(t3) #if CONFIG_IDF_TARGET_ESP32P4
addi t5,t4,1 //TODO: IDF-7566
sw t5, 0x0(t3) add t3, t3, t6
#endif
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 */ /* If reached here from another low-prio ISR, skip stack pushing to TCB */
bne t4,zero, rtos_enter_end bne t4,zero, rtos_enter_end
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD #if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
/* esp_hw_stack_guard_monitor_stop(); */ /* esp_hw_stack_guard_monitor_stop(); */
@@ -54,9 +80,21 @@ rtos_int_enter:
#endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */ #endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
/* Save current TCB and load the ISR stack */ /* Save current TCB and load the ISR stack */
//TODO: IDF-7566
#if !CONFIG_IDF_TARGET_ESP32P4
lw t0, pxCurrentTCB lw t0, pxCurrentTCB
sw sp, 0x0(t0) sw sp, 0x0(t0)
lw sp, xIsrStackTop lw sp, xIsrStackTop
#else
la t0, pxCurrentTCB /* t0 = &pxCurrentTCB */
add t0, t0, t6 /* t0 = &pxCurrentTCB[coreID] */
lw t0, (t0) /* t0 = pxCurrentTCB[coreID] */
sw t2, 0x0(t0)
lw sp, xIsrStackTop
csrr t6, mhartid
beq t6, zero, rtos_enter_end
lw sp, xIsrStackTop1
#endif
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD #if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
/* esp_hw_stack_guard_set_bounds(xIsrStack, xIsrStackTop); */ /* esp_hw_stack_guard_set_bounds(xIsrStack, xIsrStackTop); */
@@ -67,6 +105,10 @@ rtos_int_enter:
#endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */ #endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
rtos_enter_end: rtos_enter_end:
#if CONFIG_IDF_TARGET_ESP32P4
/* needs jira for p4 */
mv ra, t1
#endif
ret ret
/** /**
@@ -76,11 +118,25 @@ rtos_enter_end:
.type rtos_int_exit, @function .type rtos_int_exit, @function
rtos_int_exit: rtos_int_exit:
/* may skip RTOS aware interrupt since scheduler was not started */ /* may skip RTOS aware interrupt since scheduler was not started */
//TODO: IDF-7566
#if !CONFIG_IDF_TARGET_ESP32P4
lw t0, uxSchedulerRunning lw t0, uxSchedulerRunning
#else
csrr t1, mhartid
slli t1, t1, 2
la t0, uxSchedulerRunning /* t0 = &uxSchedulerRunning */
add t0, t0, t1 /* t0 = &uxSchedulerRunning[coreID] */
lw t0, (t0)
#endif
beq t0,zero, rtos_exit_end beq t0,zero, rtos_exit_end
/* update nesting interrupts counter */ /* update nesting interrupts counter */
la t2, uxInterruptNesting la t2, uxInterruptNesting
#if CONFIG_IDF_TARGET_ESP32P4
//TODO: IDF-7566
add t2, t2, t1
#endif
lw t3, 0x0(t2) lw t3, 0x0(t2)
/* Already zero, protect against underflow */ /* Already zero, protect against underflow */
@@ -95,6 +151,10 @@ isr_skip_decrement:
/* Schedule the next task if a yield is pending */ /* Schedule the next task if a yield is pending */
la t0, xPortSwitchFlag la t0, xPortSwitchFlag
#if CONFIG_IDF_TARGET_ESP32P4
//TODO: IDF-7566
add t0, t0, t1
#endif
lw t2, 0x0(t0) lw t2, 0x0(t0)
beq t2, zero, no_switch beq t2, zero, no_switch
@@ -108,11 +168,19 @@ isr_skip_decrement:
/* Clears the switch pending flag */ /* Clears the switch pending flag */
la t0, xPortSwitchFlag la t0, xPortSwitchFlag
#if CONFIG_IDF_TARGET_ESP32P4
//TODO: IDF-7566
/* c routine vTaskSwitchContext may change the temp registers, so we read again */
csrr t3, mhartid
slli t3, t3, 2
add t0, t0, t3
#endif
mv t2, zero mv t2, zero
sw t2, 0x0(t0) sw t2, 0x0(t0)
no_switch: no_switch:
#if !CONFIG_IDF_TARGET_ESP32P4 //TODO: IDF-7566
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD #if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
/* esp_hw_stack_guard_monitor_stop(); */ /* esp_hw_stack_guard_monitor_stop(); */
ESP_HW_STACK_GUARD_MONITOR_STOP_CPU0 ESP_HW_STACK_GUARD_MONITOR_STOP_CPU0
@@ -133,5 +201,16 @@ no_switch:
ESP_HW_STACK_GUARD_MONITOR_START_CPU0 ESP_HW_STACK_GUARD_MONITOR_START_CPU0
#endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */ #endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
#else
/* Recover the stack of next task and prepare to exit : */
la a0, pxCurrentTCB
/* We may come here from a branch, so we re-cal here */
csrr t3, mhartid
slli t3, t3, 2
add a0, a0, t3 /* a0 = &pxCurrentTCB[coreID] */
lw a0, (a0) /* a0 = pxCurrentTCB[coreID] */
lw a0, 0x0(a0) /* a0 = previous sp */
#endif //#if !CONFIG_IDF_TARGET_ESP32P4
rtos_exit_end: rtos_exit_end:
ret ret

View File

@@ -3,7 +3,7 @@
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
* SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD
*/ */
/* /*
@@ -185,6 +185,8 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
//TODO: IDF-7566
#if !CONFIG_IDF_TARGET_ESP32P4
#define taskSELECT_HIGHEST_PRIORITY_TASK() \ #define taskSELECT_HIGHEST_PRIORITY_TASK() \
{ \ { \
UBaseType_t uxTopPriority; \ UBaseType_t uxTopPriority; \
@@ -194,6 +196,17 @@
configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \ configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB[ 0 ], &( pxReadyTasksLists[ uxTopPriority ] ) ); \ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB[ 0 ], &( pxReadyTasksLists[ uxTopPriority ] ) ); \
} /* taskSELECT_HIGHEST_PRIORITY_TASK() */ } /* taskSELECT_HIGHEST_PRIORITY_TASK() */
#else
#define taskSELECT_HIGHEST_PRIORITY_TASK() \
{ \
UBaseType_t uxTopPriority; \
\
/* Find the highest priority list that contains ready tasks. */ \
portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \
configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB[ xPortGetCoreID() ], &( pxReadyTasksLists[ uxTopPriority ] ) ); \
} /* taskSELECT_HIGHEST_PRIORITY_TASK() */
#endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View File

@@ -30,6 +30,7 @@ menu "FreeRTOS"
# Todo: Replace with CONFIG_NUM_CORES (IDF-4986) # Todo: Replace with CONFIG_NUM_CORES (IDF-4986)
bool "Run FreeRTOS only on first core" bool "Run FreeRTOS only on first core"
default "y" if IDF_TARGET_ESP32S2 || IDF_TARGET_LINUX default "y" if IDF_TARGET_ESP32S2 || IDF_TARGET_LINUX
default "y" if IDF_TARGET_ESP32P4 #TODO: IDF-7566
select ESP_SYSTEM_SINGLE_CORE_MODE select ESP_SYSTEM_SINGLE_CORE_MODE
help help
This version of FreeRTOS normally takes control of all cores of the CPU. Select this if you only want This version of FreeRTOS normally takes control of all cores of the CPU. Select this if you only want

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -111,10 +111,19 @@ void esp_startup_start_app_other_cores(void)
} }
// Wait for CPU0 to start FreeRTOS before progressing // Wait for CPU0 to start FreeRTOS before progressing
//TODO: IDF-7566
#if !CONFIG_IDF_TARGET_ESP32P4
extern volatile unsigned port_xSchedulerRunning[portNUM_PROCESSORS]; extern volatile unsigned port_xSchedulerRunning[portNUM_PROCESSORS];
while (port_xSchedulerRunning[0] == 0) { while (port_xSchedulerRunning[0] == 0) {
; ;
} }
#else
extern volatile unsigned uxSchedulerRunning[portNUM_PROCESSORS];
while (uxSchedulerRunning[0] == 0) {
;
}
#endif
#if CONFIG_APPTRACE_ENABLE #if CONFIG_APPTRACE_ENABLE
// [refactor-todo] move to esp_system initialization // [refactor-todo] move to esp_system initialization

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -64,7 +64,17 @@ void vSystimerSetup(void)
/* Systimer HAL layer object */ /* Systimer HAL layer object */
static systimer_hal_context_t systimer_hal; static systimer_hal_context_t systimer_hal;
/* set system timer interrupt vector */ /* set system timer interrupt vector */
/**
* TODO: IDF-7487
* ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE is renamed to ETS_SYSTIMER_TARGET0_INTR_SOURCE.
* It's said that this interrupt is never an edge type, for previous all chips. You may need to check this and unify the name.
*/
#if !CONFIG_IDF_TARGET_ESP32P4
ESP_ERROR_CHECK(esp_intr_alloc(ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE + cpuid, ESP_INTR_FLAG_IRAM | level, SysTickIsrHandler, &systimer_hal, NULL)); ESP_ERROR_CHECK(esp_intr_alloc(ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE + cpuid, ESP_INTR_FLAG_IRAM | level, SysTickIsrHandler, &systimer_hal, NULL));
#else
ESP_ERROR_CHECK(esp_intr_alloc(ETS_SYSTIMER_TARGET0_INTR_SOURCE + cpuid, ESP_INTR_FLAG_IRAM | level, SysTickIsrHandler, &systimer_hal, NULL));
#endif
if (cpuid == 0) { if (cpuid == 0) {
periph_module_enable(PERIPH_SYSTIMER_MODULE); periph_module_enable(PERIPH_SYSTIMER_MODULE);