forked from espressif/esp-idf
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:
@@ -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
|
#define configTASKLIST_INCLUDE_COREID 1
|
||||||
#endif
|
#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 -------------------------
|
// ---------------------- Features -------------------------
|
||||||
|
|
||||||
/* These currently aren't required, but could be useful additions in the future */
|
/* 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();
|
return xPortCheckIfInISR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Added for backward compatibility with IDF
|
||||||
|
#define xPortInterruptedFromISRContext() xPortInIsrContext()
|
||||||
|
|
||||||
// ---------------------- Spinlocks ------------------------
|
// ---------------------- 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
|
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.
|
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 vPortEnterCritical(void);
|
||||||
void vPortExitCriticalIDF(void);
|
void vPortExitCritical(void);
|
||||||
|
|
||||||
//IDF task critical sections
|
//IDF task critical sections
|
||||||
#define portTRY_ENTER_CRITICAL(lock, timeout) {((void) lock; (void) timeout; vPortEnterCriticalIDF(); pdPASS;)}
|
#define portTRY_ENTER_CRITICAL(lock, timeout) {((void) lock; (void) timeout; vPortEnterCritical(); pdPASS;)}
|
||||||
#define portENTER_CRITICAL_IDF(lock) ({(void) lock; vPortEnterCriticalIDF();})
|
#define portENTER_CRITICAL_IDF(lock) ({(void) lock; vPortEnterCritical();})
|
||||||
#define portEXIT_CRITICAL_IDF(lock) ({(void) lock; vPortExitCriticalIDF();})
|
#define portEXIT_CRITICAL_IDF(lock) ({(void) lock; vPortExitCritical();})
|
||||||
//IDF ISR critical sections
|
//IDF ISR critical sections
|
||||||
#define portTRY_ENTER_CRITICAL_ISR(lock, timeout) {((void) lock; (void) timeout; vPortEnterCriticalIDF(); pdPASS;)}
|
#define portTRY_ENTER_CRITICAL_ISR(lock, timeout) {((void) lock; (void) timeout; vPortEnterCritical(); pdPASS;)}
|
||||||
#define portENTER_CRITICAL_ISR(lock) ({(void) lock; vPortEnterCriticalIDF();})
|
#define portENTER_CRITICAL_ISR(lock) ({(void) lock; vPortEnterCritical();})
|
||||||
#define portEXIT_CRITICAL_ISR(lock) ({(void) lock; vPortExitCriticalIDF();})
|
#define portEXIT_CRITICAL_ISR(lock) ({(void) lock; vPortExitCritical();})
|
||||||
//IDF safe critical sections (they're the same)
|
//IDF safe critical sections (they're the same)
|
||||||
#define portENTER_CRITICAL_SAFE(lock) ({(void) lock; vPortEnterCriticalIDF();})
|
#define portENTER_CRITICAL_SAFE(lock) ({(void) lock; vPortEnterCritical();})
|
||||||
#define portEXIT_CRITICAL_SAFE(lock) ({(void) lock; vPortExitCriticalIDF();})
|
#define portEXIT_CRITICAL_SAFE(lock) ({(void) lock; vPortExitCritical();})
|
||||||
|
|
||||||
// ---------------------- Yielding -------------------------
|
// ---------------------- Yielding -------------------------
|
||||||
|
|
||||||
@@ -307,6 +314,9 @@ static inline bool IRAM_ATTR xPortCanYield(void)
|
|||||||
return (threshold <= 1);
|
return (threshold <= 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Added for backward compatibility with IDF
|
||||||
|
#define portYIELD_WITHIN_API() vTaskYieldWithinAPI()
|
||||||
|
|
||||||
// ----------------------- System --------------------------
|
// ----------------------- System --------------------------
|
||||||
|
|
||||||
void vPortSetStackWatchpoint(void *pxStackStart);
|
void vPortSetStackWatchpoint(void *pxStackStart);
|
||||||
@@ -329,7 +339,7 @@ void vPortSetStackWatchpoint(void *pxStackStart);
|
|||||||
// --------------------- App-Trace -------------------------
|
// --------------------- App-Trace -------------------------
|
||||||
|
|
||||||
#if CONFIG_APPTRACE_SV_ENABLE
|
#if CONFIG_APPTRACE_SV_ENABLE
|
||||||
extern int xPortSwitchFlag;
|
extern volatile BaseType_t xPortSwitchFlag;
|
||||||
#define os_task_switch_is_pended(_cpu_) (xPortSwitchFlag)
|
#define os_task_switch_is_pended(_cpu_) (xPortSwitchFlag)
|
||||||
#else
|
#else
|
||||||
#define os_task_switch_is_pended(_cpu_) (false)
|
#define os_task_switch_is_pended(_cpu_) (false)
|
||||||
|
@@ -38,6 +38,9 @@
|
|||||||
#include "esp_private/pm_trace.h"
|
#include "esp_private/pm_trace.h"
|
||||||
#endif //CONFIG_PM_TRACE
|
#endif //CONFIG_PM_TRACE
|
||||||
|
|
||||||
|
#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||||
|
#include "esp_gdbstub.h"
|
||||||
|
#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||||
|
|
||||||
/* ---------------------------------------------------- Variables ------------------------------------------------------
|
/* ---------------------------------------------------- Variables ------------------------------------------------------
|
||||||
*
|
*
|
||||||
@@ -63,7 +66,7 @@ static UBaseType_t port_uxCriticalOldInterruptStateIDF = 0;
|
|||||||
|
|
||||||
// ------------------ Critical Sections --------------------
|
// ------------------ Critical Sections --------------------
|
||||||
|
|
||||||
void vPortEnterCriticalIDF(void)
|
void vPortEnterCritical(void)
|
||||||
{
|
{
|
||||||
// Save current interrupt threshold and disable interrupts
|
// Save current interrupt threshold and disable interrupts
|
||||||
UBaseType_t old_thresh = ulPortSetInterruptMask();
|
UBaseType_t old_thresh = ulPortSetInterruptMask();
|
||||||
@@ -75,7 +78,7 @@ void vPortEnterCriticalIDF(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vPortExitCriticalIDF(void)
|
void vPortExitCritical(void)
|
||||||
{
|
{
|
||||||
if (port_uxCriticalNestingIDF > 0) {
|
if (port_uxCriticalNestingIDF > 0) {
|
||||||
port_uxCriticalNestingIDF--;
|
port_uxCriticalNestingIDF--;
|
||||||
|
@@ -356,6 +356,9 @@ static inline bool IRAM_ATTR xPortCanYield(void)
|
|||||||
return ((ps_reg & PS_INTLEVEL_MASK) == 0);
|
return ((ps_reg & PS_INTLEVEL_MASK) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Added for backward compatibility with IDF
|
||||||
|
#define portYIELD_WITHIN_API() vTaskYieldWithinAPI()
|
||||||
|
|
||||||
// ----------------------- System --------------------------
|
// ----------------------- System --------------------------
|
||||||
|
|
||||||
void vPortSetStackWatchpoint(void *pxStackStart);
|
void vPortSetStackWatchpoint(void *pxStackStart);
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#include "esp_task_wdt.h"
|
#include "esp_task_wdt.h"
|
||||||
#include "esp_heap_caps_init.h"
|
#include "esp_heap_caps_init.h"
|
||||||
#include "esp_freertos_hooks.h"
|
#include "esp_freertos_hooks.h"
|
||||||
|
#include "esp_intr_alloc.h"
|
||||||
#if CONFIG_SPIRAM
|
#if CONFIG_SPIRAM
|
||||||
/* Required by esp_psram_extram_reserve_dma_pool() */
|
/* Required by esp_psram_extram_reserve_dma_pool() */
|
||||||
#include "esp_psram.h"
|
#include "esp_psram.h"
|
||||||
@@ -38,6 +39,12 @@
|
|||||||
#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||||
#include "esp_gdbstub.h" /* Required by esp_gdbstub_init() */
|
#include "esp_gdbstub.h" /* Required by esp_gdbstub_init() */
|
||||||
#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
#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
|
OS state variables
|
||||||
@@ -148,6 +155,9 @@ void vPortSetStackWatchpoint( void *pxStackStart )
|
|||||||
|
|
||||||
// ---------------------- Tick Timer -----------------------
|
// ---------------------- Tick Timer -----------------------
|
||||||
|
|
||||||
|
BaseType_t xPortSysTickHandler(void);
|
||||||
|
|
||||||
|
#ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
extern void _frxt_tick_timer_init(void);
|
extern void _frxt_tick_timer_init(void);
|
||||||
extern void _xt_tick_divisor_init(void);
|
extern void _xt_tick_divisor_init(void);
|
||||||
|
|
||||||
@@ -163,6 +173,108 @@ void vPortSetupTimer(void)
|
|||||||
_frxt_tick_timer_init();
|
_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 ----------------------
|
// --------------------- App Start-up ----------------------
|
||||||
|
|
||||||
static const char *TAG = "cpu_start";
|
static const char *TAG = "cpu_start";
|
||||||
|
@@ -709,11 +709,17 @@ static void prvYieldCore( BaseType_t xCoreID )
|
|||||||
{
|
{
|
||||||
xYieldPendings[ xCoreID ] = pdTRUE;
|
xYieldPendings[ xCoreID ] = pdTRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
|
// TODO: IDF-5256
|
||||||
|
#if ( configNUM_CORES > 1 )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
portYIELD_CORE( xCoreID );
|
portYIELD_CORE( xCoreID );
|
||||||
pxCurrentTCBs[ xCoreID ]->xTaskRunState = taskTASK_YIELDING;
|
pxCurrentTCBs[ xCoreID ]->xTaskRunState = taskTASK_YIELDING;
|
||||||
}
|
}
|
||||||
|
#endif /* ( configNUM_CORES > 1 ) */
|
||||||
|
#endif /* ESP_PLATFORM */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user