mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'bugfix/freertos_smp_build_test_failures' into 'master'
freertos-smp: Fix build test issues for s2, s3, c3 with FreeRTOS SMP enabled See merge request espressif/esp-idf!18564
This commit is contained in:
commit
089d88da77
@ -259,15 +259,6 @@ Default values for trace macros added by ESP-IDF and are not part of Vanilla Fre
|
||||
#define configTASKLIST_INCLUDE_COREID 1
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
extern uint32_t port_switch_flag[];
|
||||
#define os_task_switch_is_pended(_cpu_) (port_switch_flag[_cpu_])
|
||||
#else
|
||||
#define os_task_switch_is_pended(_cpu_) (false)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ---------------------- Features -------------------------
|
||||
|
||||
/* These currently aren't required, but could be useful additions in the future */
|
||||
|
@ -238,6 +238,9 @@ static inline BaseType_t xPortInIsrContext(void)
|
||||
return xPortCheckIfInISR();
|
||||
}
|
||||
|
||||
// Added for backward compatibility with IDF
|
||||
#define xPortInterruptedFromISRContext() xPortInIsrContext()
|
||||
|
||||
// ---------------------- Spinlocks ------------------------
|
||||
|
||||
/**
|
||||
@ -279,21 +282,25 @@ static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t comp
|
||||
/*
|
||||
IDF style critical sections which are orthogonal to FreeRTOS critical sections. However, on single core, the IDF style
|
||||
critical sections simply disable interrupts, thus we discard the lock and timeout arguments.
|
||||
|
||||
Note: The IDF Style critical sections are named differently to their counterparts present in the xtensa port as few IDF
|
||||
examples such as esp_zigbee_gateway, when compiled for RISC-V targets, have a reference to vPortEnterCritical()
|
||||
and vPortExitCritical() from precompiled libraries (.a) thereby failing linking.
|
||||
*/
|
||||
void vPortEnterCriticalIDF(void);
|
||||
void vPortExitCriticalIDF(void);
|
||||
void vPortEnterCritical(void);
|
||||
void vPortExitCritical(void);
|
||||
|
||||
//IDF task critical sections
|
||||
#define portTRY_ENTER_CRITICAL(lock, timeout) {((void) lock; (void) timeout; vPortEnterCriticalIDF(); pdPASS;)}
|
||||
#define portENTER_CRITICAL_IDF(lock) ({(void) lock; vPortEnterCriticalIDF();})
|
||||
#define portEXIT_CRITICAL_IDF(lock) ({(void) lock; vPortExitCriticalIDF();})
|
||||
#define portTRY_ENTER_CRITICAL(lock, timeout) {((void) lock; (void) timeout; vPortEnterCritical(); pdPASS;)}
|
||||
#define portENTER_CRITICAL_IDF(lock) ({(void) lock; vPortEnterCritical();})
|
||||
#define portEXIT_CRITICAL_IDF(lock) ({(void) lock; vPortExitCritical();})
|
||||
//IDF ISR critical sections
|
||||
#define portTRY_ENTER_CRITICAL_ISR(lock, timeout) {((void) lock; (void) timeout; vPortEnterCriticalIDF(); pdPASS;)}
|
||||
#define portENTER_CRITICAL_ISR(lock) ({(void) lock; vPortEnterCriticalIDF();})
|
||||
#define portEXIT_CRITICAL_ISR(lock) ({(void) lock; vPortExitCriticalIDF();})
|
||||
#define portTRY_ENTER_CRITICAL_ISR(lock, timeout) {((void) lock; (void) timeout; vPortEnterCritical(); pdPASS;)}
|
||||
#define portENTER_CRITICAL_ISR(lock) ({(void) lock; vPortEnterCritical();})
|
||||
#define portEXIT_CRITICAL_ISR(lock) ({(void) lock; vPortExitCritical();})
|
||||
//IDF safe critical sections (they're the same)
|
||||
#define portENTER_CRITICAL_SAFE(lock) ({(void) lock; vPortEnterCriticalIDF();})
|
||||
#define portEXIT_CRITICAL_SAFE(lock) ({(void) lock; vPortExitCriticalIDF();})
|
||||
#define portENTER_CRITICAL_SAFE(lock) ({(void) lock; vPortEnterCritical();})
|
||||
#define portEXIT_CRITICAL_SAFE(lock) ({(void) lock; vPortExitCritical();})
|
||||
|
||||
// ---------------------- Yielding -------------------------
|
||||
|
||||
@ -307,6 +314,9 @@ static inline bool IRAM_ATTR xPortCanYield(void)
|
||||
return (threshold <= 1);
|
||||
}
|
||||
|
||||
// Added for backward compatibility with IDF
|
||||
#define portYIELD_WITHIN_API() vTaskYieldWithinAPI()
|
||||
|
||||
// ----------------------- System --------------------------
|
||||
|
||||
void vPortSetStackWatchpoint(void *pxStackStart);
|
||||
@ -329,7 +339,7 @@ void vPortSetStackWatchpoint(void *pxStackStart);
|
||||
// --------------------- App-Trace -------------------------
|
||||
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
extern int xPortSwitchFlag;
|
||||
extern volatile BaseType_t xPortSwitchFlag;
|
||||
#define os_task_switch_is_pended(_cpu_) (xPortSwitchFlag)
|
||||
#else
|
||||
#define os_task_switch_is_pended(_cpu_) (false)
|
||||
|
@ -38,6 +38,9 @@
|
||||
#include "esp_private/pm_trace.h"
|
||||
#endif //CONFIG_PM_TRACE
|
||||
|
||||
#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||
#include "esp_gdbstub.h"
|
||||
#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||
|
||||
/* ---------------------------------------------------- Variables ------------------------------------------------------
|
||||
*
|
||||
@ -63,7 +66,7 @@ static UBaseType_t port_uxCriticalOldInterruptStateIDF = 0;
|
||||
|
||||
// ------------------ Critical Sections --------------------
|
||||
|
||||
void vPortEnterCriticalIDF(void)
|
||||
void vPortEnterCritical(void)
|
||||
{
|
||||
// Save current interrupt threshold and disable interrupts
|
||||
UBaseType_t old_thresh = ulPortSetInterruptMask();
|
||||
@ -75,7 +78,7 @@ void vPortEnterCriticalIDF(void)
|
||||
}
|
||||
}
|
||||
|
||||
void vPortExitCriticalIDF(void)
|
||||
void vPortExitCritical(void)
|
||||
{
|
||||
if (port_uxCriticalNestingIDF > 0) {
|
||||
port_uxCriticalNestingIDF--;
|
||||
|
@ -356,6 +356,9 @@ static inline bool IRAM_ATTR xPortCanYield(void)
|
||||
return ((ps_reg & PS_INTLEVEL_MASK) == 0);
|
||||
}
|
||||
|
||||
// Added for backward compatibility with IDF
|
||||
#define portYIELD_WITHIN_API() vTaskYieldWithinAPI()
|
||||
|
||||
// ----------------------- System --------------------------
|
||||
|
||||
void vPortSetStackWatchpoint(void *pxStackStart);
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "esp_task_wdt.h"
|
||||
#include "esp_heap_caps_init.h"
|
||||
#include "esp_freertos_hooks.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#if CONFIG_SPIRAM
|
||||
/* Required by esp_psram_extram_reserve_dma_pool() */
|
||||
#include "esp_psram.h"
|
||||
@ -38,6 +39,12 @@
|
||||
#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||
#include "esp_gdbstub.h" /* Required by esp_gdbstub_init() */
|
||||
#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||
#ifdef CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/system_reg.h"
|
||||
#include "hal/systimer_hal.h"
|
||||
#include "hal/systimer_ll.h"
|
||||
#endif // CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
|
||||
|
||||
/*
|
||||
OS state variables
|
||||
@ -148,6 +155,9 @@ void vPortSetStackWatchpoint( void *pxStackStart )
|
||||
|
||||
// ---------------------- Tick Timer -----------------------
|
||||
|
||||
BaseType_t xPortSysTickHandler(void);
|
||||
|
||||
#ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||
extern void _frxt_tick_timer_init(void);
|
||||
extern void _xt_tick_divisor_init(void);
|
||||
|
||||
@ -163,6 +173,108 @@ void vPortSetupTimer(void)
|
||||
_frxt_tick_timer_init();
|
||||
}
|
||||
|
||||
#elif CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
|
||||
|
||||
_Static_assert(SOC_CPU_CORES_NUM <= SOC_SYSTIMER_ALARM_NUM - 1, "the number of cores must match the number of core alarms in SYSTIMER");
|
||||
|
||||
void SysTickIsrHandler(void *arg);
|
||||
|
||||
static uint32_t s_handled_systicks[portNUM_PROCESSORS] = { 0 };
|
||||
|
||||
#define SYSTICK_INTR_ID (ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE)
|
||||
|
||||
/**
|
||||
* @brief Set up the systimer peripheral to generate the tick interrupt
|
||||
*
|
||||
* Both timer alarms are configured in periodic mode.
|
||||
* It is done at the same time so SysTicks for both CPUs occur at the same time or very close.
|
||||
* Shifts a time of triggering interrupts for core 0 and core 1.
|
||||
*/
|
||||
void vPortSetupTimer(void)
|
||||
{
|
||||
unsigned cpuid = xPortGetCoreID();
|
||||
#ifdef CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL3
|
||||
const unsigned level = ESP_INTR_FLAG_LEVEL3;
|
||||
#else
|
||||
const unsigned level = ESP_INTR_FLAG_LEVEL1;
|
||||
#endif
|
||||
/* Systimer HAL layer object */
|
||||
static systimer_hal_context_t systimer_hal;
|
||||
/* set system timer interrupt vector */
|
||||
ESP_ERROR_CHECK(esp_intr_alloc(ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE + cpuid, ESP_INTR_FLAG_IRAM | level, SysTickIsrHandler, &systimer_hal, NULL));
|
||||
|
||||
if (cpuid == 0) {
|
||||
systimer_hal_init(&systimer_hal);
|
||||
systimer_ll_set_counter_value(systimer_hal.dev, SYSTIMER_LL_COUNTER_OS_TICK, 0);
|
||||
systimer_ll_apply_counter_value(systimer_hal.dev, SYSTIMER_LL_COUNTER_OS_TICK);
|
||||
|
||||
for (cpuid = 0; cpuid < SOC_CPU_CORES_NUM; cpuid++) {
|
||||
systimer_hal_counter_can_stall_by_cpu(&systimer_hal, SYSTIMER_LL_COUNTER_OS_TICK, cpuid, false);
|
||||
}
|
||||
|
||||
for (cpuid = 0; cpuid < portNUM_PROCESSORS; ++cpuid) {
|
||||
uint32_t alarm_id = SYSTIMER_LL_ALARM_OS_TICK_CORE0 + cpuid;
|
||||
|
||||
/* configure the timer */
|
||||
systimer_hal_connect_alarm_counter(&systimer_hal, alarm_id, SYSTIMER_LL_COUNTER_OS_TICK);
|
||||
systimer_hal_set_alarm_period(&systimer_hal, alarm_id, 1000000UL / CONFIG_FREERTOS_HZ);
|
||||
systimer_hal_select_alarm_mode(&systimer_hal, alarm_id, SYSTIMER_ALARM_MODE_PERIOD);
|
||||
systimer_hal_counter_can_stall_by_cpu(&systimer_hal, SYSTIMER_LL_COUNTER_OS_TICK, cpuid, true);
|
||||
if (cpuid == 0) {
|
||||
systimer_hal_enable_alarm_int(&systimer_hal, alarm_id);
|
||||
systimer_hal_enable_counter(&systimer_hal, SYSTIMER_LL_COUNTER_OS_TICK);
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
// SysTick of core 0 and core 1 are shifted by half of period
|
||||
systimer_hal_counter_value_advance(&systimer_hal, SYSTIMER_LL_COUNTER_OS_TICK, 1000000UL / CONFIG_FREERTOS_HZ / 2);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint32_t alarm_id = SYSTIMER_LL_ALARM_OS_TICK_CORE0 + cpuid;
|
||||
systimer_hal_enable_alarm_int(&systimer_hal, alarm_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Systimer interrupt handler.
|
||||
*
|
||||
* The Systimer interrupt for SysTick works in periodic mode no need to calc the next alarm.
|
||||
* If a timer interrupt is ever serviced more than one tick late, it is necessary to process multiple ticks.
|
||||
*/
|
||||
IRAM_ATTR void SysTickIsrHandler(void *arg)
|
||||
{
|
||||
uint32_t cpuid = xPortGetCoreID();
|
||||
systimer_hal_context_t *systimer_hal = (systimer_hal_context_t *)arg;
|
||||
#ifdef CONFIG_PM_TRACE
|
||||
ESP_PM_TRACE_ENTER(TICK, cpuid);
|
||||
#endif
|
||||
|
||||
uint32_t alarm_id = SYSTIMER_LL_ALARM_OS_TICK_CORE0 + cpuid;
|
||||
do {
|
||||
systimer_ll_clear_alarm_int(systimer_hal->dev, alarm_id);
|
||||
|
||||
uint32_t diff = systimer_hal_get_counter_value(systimer_hal, SYSTIMER_LL_COUNTER_OS_TICK) / systimer_ll_get_alarm_period(systimer_hal->dev, alarm_id) - s_handled_systicks[cpuid];
|
||||
if (diff > 0) {
|
||||
if (s_handled_systicks[cpuid] == 0) {
|
||||
s_handled_systicks[cpuid] = diff;
|
||||
diff = 1;
|
||||
} else {
|
||||
s_handled_systicks[cpuid] += diff;
|
||||
}
|
||||
|
||||
do {
|
||||
xPortSysTickHandler();
|
||||
} while (--diff);
|
||||
}
|
||||
} while (systimer_ll_is_alarm_int_fired(systimer_hal->dev, alarm_id));
|
||||
|
||||
#ifdef CONFIG_PM_TRACE
|
||||
ESP_PM_TRACE_EXIT(TICK, cpuid);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||
|
||||
// --------------------- App Start-up ----------------------
|
||||
|
||||
static const char *TAG = "cpu_start";
|
||||
|
@ -709,11 +709,17 @@ static void prvYieldCore( BaseType_t xCoreID )
|
||||
{
|
||||
xYieldPendings[ xCoreID ] = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
portYIELD_CORE( xCoreID );
|
||||
pxCurrentTCBs[ xCoreID ]->xTaskRunState = taskTASK_YIELDING;
|
||||
}
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
// TODO: IDF-5256
|
||||
#if ( configNUM_CORES > 1 )
|
||||
else
|
||||
{
|
||||
portYIELD_CORE( xCoreID );
|
||||
pxCurrentTCBs[ xCoreID ]->xTaskRunState = taskTASK_YIELDING;
|
||||
}
|
||||
#endif /* ( configNUM_CORES > 1 ) */
|
||||
#endif /* ESP_PLATFORM */
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user