freertos: Refactor port_systick

This commit refactors port_systick.c so that all ports (RISC-V vs Xtensa) of
all FreeRTOS implementations (IDF vs Amazon SMP FreeRTOS) use the same set of
tick interrupt functions. Thus, these funcitons are now common:

- vPortSetupTimer() to setup the tick interrupt's timer
- xPortSysTickHandler() that is called on each tick interrupt
This commit is contained in:
Darian Leung
2023-04-24 16:08:51 +08:00
parent cf595293af
commit 76d4c9f592
5 changed files with 101 additions and 369 deletions

View File

@@ -27,6 +27,7 @@
#include "esp_log.h"
#include "FreeRTOS.h" /* This pulls in portmacro.h */
#include "task.h"
#include "port_systick.h"
#include "portmacro.h"
#include "esp_memory_utils.h"
#ifdef CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
@@ -98,127 +99,6 @@ void vPortSetStackWatchpoint(void *pxStackStart)
esp_cpu_set_watchpoint(STACK_WATCH_POINT_NUMBER, (char *)addr, STACK_WATCH_AREA_SIZE, ESP_CPU_WATCHPOINT_STORE);
}
// ---------------------- Tick Timer -----------------------
BaseType_t xPortSysTickHandler(void);
#ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
#ifdef CONFIG_FREERTOS_CORETIMER_0
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER0_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
#endif
#ifdef CONFIG_FREERTOS_CORETIMER_1
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER1_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
#endif
#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) {
periph_module_enable(PERIPH_SYSTIMER_MODULE);
systimer_hal_init(&systimer_hal);
systimer_hal_tick_rate_ops_t ops = {
.ticks_to_us = systimer_ticks_to_us,
.us_to_ticks = systimer_us_to_ticks,
};
systimer_hal_set_tick_rate_ops(&systimer_hal, &ops);
systimer_ll_set_counter_value(systimer_hal.dev, SYSTIMER_COUNTER_OS_TICK, 0);
systimer_ll_apply_counter_value(systimer_hal.dev, SYSTIMER_COUNTER_OS_TICK);
for (cpuid = 0; cpuid < SOC_CPU_CORES_NUM; cpuid++) {
systimer_hal_counter_can_stall_by_cpu(&systimer_hal, SYSTIMER_COUNTER_OS_TICK, cpuid, false);
}
for (cpuid = 0; cpuid < portNUM_PROCESSORS; ++cpuid) {
uint32_t alarm_id = SYSTIMER_ALARM_OS_TICK_CORE0 + cpuid;
/* configure the timer */
systimer_hal_connect_alarm_counter(&systimer_hal, alarm_id, SYSTIMER_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_COUNTER_OS_TICK, cpuid, true);
if (cpuid == 0) {
systimer_hal_enable_alarm_int(&systimer_hal, alarm_id);
systimer_hal_enable_counter(&systimer_hal, SYSTIMER_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_COUNTER_OS_TICK, 1000000UL / CONFIG_FREERTOS_HZ / 2);
#endif
}
}
} else {
uint32_t alarm_id = SYSTIMER_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_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_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_SYSTIMER
/* ---------------------------------------------- Port Implementations -------------------------------------------------
@@ -562,28 +442,6 @@ void vPortTLSPointersDelCb( void *pxTCB )
}
#endif // CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS
// -------------------- Tick Handler -----------------------
extern void esp_vApplicationIdleHook(void);
extern void esp_vApplicationTickHook(void);
BaseType_t xPortSysTickHandler(void)
{
#if configBENCHMARK
portbenchmarkIntLatency();
#endif //configBENCHMARK
traceISR_ENTER(SYSTICK_INTR_ID);
BaseType_t ret = xTaskIncrementTick();
//Manually call the IDF tick hooks
esp_vApplicationTickHook();
if (ret != pdFALSE) {
portYIELD_FROM_ISR();
} else {
traceISR_EXIT();
}
return ret;
}
// ------------------- Hook Functions ----------------------
void __attribute__((weak)) vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
@@ -608,6 +466,7 @@ void vApplicationTickHook( void )
}
#endif
extern void esp_vApplicationIdleHook(void);
#if CONFIG_FREERTOS_USE_MINIMAL_IDLE_HOOK
/*
By default, the port uses vApplicationMinimalIdleHook() to run IDF style idle

View File

@@ -9,6 +9,7 @@
#include <string.h>
#include "FreeRTOS.h"
#include "task.h" //For vApplicationStackOverflowHook
#include "port_systick.h"
#include "portmacro.h"
#include "spinlock.h"
#include "xt_instr_macros.h"
@@ -174,141 +175,6 @@ void vPortSetStackWatchpoint( void *pxStackStart )
esp_cpu_set_watchpoint(STACK_WATCH_POINT_NUMBER, (char *)addr, 32, ESP_CPU_WATCHPOINT_STORE);
}
// ---------------------- 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);
#ifdef CONFIG_FREERTOS_CORETIMER_0
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER0_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
#endif
#ifdef CONFIG_FREERTOS_CORETIMER_1
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER1_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
#endif
/**
* @brief Initialize CCONT timer to generate the tick interrupt
*
*/
void vPortSetupTimer(void)
{
/* Init the tick divisor value */
_xt_tick_divisor_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) {
periph_module_enable(PERIPH_SYSTIMER_MODULE);
systimer_hal_init(&systimer_hal);
systimer_hal_tick_rate_ops_t ops = {
.ticks_to_us = systimer_ticks_to_us,
.us_to_ticks = systimer_us_to_ticks,
};
systimer_hal_set_tick_rate_ops(&systimer_hal, &ops);
systimer_ll_set_counter_value(systimer_hal.dev, SYSTIMER_COUNTER_OS_TICK, 0);
systimer_ll_apply_counter_value(systimer_hal.dev, SYSTIMER_COUNTER_OS_TICK);
for (cpuid = 0; cpuid < SOC_CPU_CORES_NUM; cpuid++) {
systimer_hal_counter_can_stall_by_cpu(&systimer_hal, SYSTIMER_COUNTER_OS_TICK, cpuid, false);
}
for (cpuid = 0; cpuid < portNUM_PROCESSORS; ++cpuid) {
uint32_t alarm_id = SYSTIMER_ALARM_OS_TICK_CORE0 + cpuid;
/* configure the timer */
systimer_hal_connect_alarm_counter(&systimer_hal, alarm_id, SYSTIMER_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_COUNTER_OS_TICK, cpuid, true);
if (cpuid == 0) {
systimer_hal_enable_alarm_int(&systimer_hal, alarm_id);
systimer_hal_enable_counter(&systimer_hal, SYSTIMER_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_COUNTER_OS_TICK, 1000000UL / CONFIG_FREERTOS_HZ / 2);
#endif
}
}
} else {
uint32_t alarm_id = SYSTIMER_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_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_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
/* ---------------------------------------------- Port Implementations -------------------------------------------------
@@ -749,31 +615,6 @@ void vPortTLSPointersDelCb( void *pxTCB )
}
#endif // CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS
// -------------------- Tick Handler -----------------------
extern void esp_vApplicationIdleHook(void);
extern void esp_vApplicationTickHook(void);
BaseType_t xPortSysTickHandler(void)
{
portbenchmarkIntLatency();
traceISR_ENTER(SYSTICK_INTR_ID);
BaseType_t ret;
esp_vApplicationTickHook();
if (portGET_CORE_ID() == 0) {
// FreeRTOS SMP requires that only core 0 calls xTaskIncrementTick()
ret = xTaskIncrementTick();
} else {
ret = pdFALSE;
}
if (ret != pdFALSE) {
portYIELD_FROM_ISR();
} else {
traceISR_EXIT();
}
return ret;
}
// ------------------- Hook Functions ----------------------
#include <stdlib.h>
@@ -795,6 +636,7 @@ void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, c
}
#endif
extern void esp_vApplicationIdleHook(void);
#if CONFIG_FREERTOS_USE_MINIMAL_IDLE_HOOK
/*
By default, the port uses vApplicationMinimalIdleHook() to run IDF style idle

View File

@@ -80,3 +80,15 @@ entries:
if FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y:
port_common:vApplicationGetIdleTaskMemory (default)
port_common:vApplicationGetTimerTaskMemory (default)
# ------------------------------------------------------------------------------------------------------------------
# port_systick.c
# - Default: Place all functions in internal RAM.
# - CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH: Place functions in flash if they are never called from an ISR
# context (directly or indirectly).
# ------------------------------------------------------------------------------------------------------------------
port_systick(noflash_text)
if FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y:
if FREERTOS_SYSTICK_USES_SYSTIMER = y:
port_systick:vSystimerSetup (default)
port_systick:vPortSetupTimer (default)

View File

@@ -208,7 +208,6 @@ entries:
# - Most functions are called from an ISR context, except for scheduler/task init/deinit functions
# --------------------------------------------------------------------------------------------------------------
if IDF_TARGET_ARCH_XTENSA = y:
port:vPortSetupTimer (default)
port:xPortStartScheduler (default)
port:vPortEndScheduler (default)
port:pvPortMalloc (default)
@@ -226,7 +225,6 @@ entries:
# - Most functions are called from an ISR context, except for scheduler/task init/deinit functions
# --------------------------------------------------------------------------------------------------------------
if IDF_TARGET_ARCH_RISCV = y:
port:vPortSetupTimer (default)
port:xPortStartScheduler (default)
port:vPortEndScheduler (default)
port:pvPortMalloc (default)

View File

@@ -4,61 +4,47 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "FreeRTOS.h"
#include "task.h"
#include "esp_intr_alloc.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_private/systimer.h"
#include "esp_private/periph_ctrl.h"
#include "sdkconfig.h"
#ifdef CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
#include "soc/periph_defs.h"
#include "hal/systimer_hal.h"
#include "hal/systimer_ll.h"
#endif
#ifdef CONFIG_PM_TRACE
#include "esp_private/pm_trace.h"
#endif //CONFIG_PM_TRACE
#if CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
#if CONFIG_FREERTOS_CORETIMER_0
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER0_INTR_SOURCE + ETS_INTERNAL_INTR_SOURCE_OFF)
#else /* CONFIG_FREERTOS_CORETIMER_1 */
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER1_INTR_SOURCE + ETS_INTERNAL_INTR_SOURCE_OFF)
#endif
#else /* CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER */
#define SYSTICK_INTR_ID (ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE)
#endif /* CONFIG_FREERTOS_SYSTICK_USES_CCOUNT */
BaseType_t xPortSysTickHandler(void);
#ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
extern void _frxt_tick_timer_init(void);
extern void _xt_tick_divisor_init(void);
/* --------------------------------------------- SYSTIMER Implementation -----------------------------------------------
* Implementation of a tick interrupt using the SYSTIMER perpiheral
* Todo: Abstract setup and operation in a separate SYSTIMER driver (IDF-6976)
* ------------------------------------------------------------------------------------------------------------------ */
#ifdef CONFIG_FREERTOS_CORETIMER_0
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER0_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
#endif
#ifdef CONFIG_FREERTOS_CORETIMER_1
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER1_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
#endif
#if CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
/**
* @brief Initialize CCONT timer to generate the tick interrupt
*
*/
void vPortSetupTimer(void)
{
/* Init the tick divisor value */
_xt_tick_divisor_init();
_frxt_tick_timer_init();
}
#elif CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
#include "soc/periph_defs.h"
#include "hal/systimer_hal.h"
#include "hal/systimer_ll.h"
#include "esp_err.h"
#include "esp_intr_alloc.h"
#include "esp_private/systimer.h"
#include "esp_private/periph_ctrl.h"
#ifdef CONFIG_PM_TRACE
#include "esp_private/pm_trace.h"
#endif //CONFIG_PM_TRACE
_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)
static uint32_t s_handled_systicks[configNUM_CORES] = { 0 };
/**
* @brief Set up the systimer peripheral to generate the tick interrupt
@@ -67,7 +53,7 @@ static uint32_t s_handled_systicks[portNUM_PROCESSORS] = { 0 };
* 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)
void vSystimerSetup(void)
{
unsigned cpuid = xPortGetCoreID();
#ifdef CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL3
@@ -124,7 +110,7 @@ void vPortSetupTimer(void)
* 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)
void SysTickIsrHandler(void *arg)
{
uint32_t cpuid = xPortGetCoreID();
systimer_hal_context_t *systimer_hal = (systimer_hal_context_t *)arg;
@@ -155,11 +141,31 @@ IRAM_ATTR void SysTickIsrHandler(void *arg)
ESP_PM_TRACE_EXIT(TICK, cpuid);
#endif
}
#endif /* CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER */
#endif // CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
/* ------------------------------------------------ Common Port Tick ---------------------------------------------------
* Tick related functions common across all ports
* ------------------------------------------------------------------------------------------------------------------ */
/**
* @brief Initialize the tick interrupt timer
*
* - CCOUNT timer is used if CONFIG_FREERTOS_SYSTICK_USES_CCOUNT is set
* - SYSTIMER is used if CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER is set
*/
void vPortSetupTimer(void)
{
#if CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
extern void _frxt_tick_timer_init(void);
extern void _xt_tick_divisor_init(void);
/* Init the tick divisor value */
_xt_tick_divisor_init();
_frxt_tick_timer_init();
#else /* CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER */
vSystimerSetup();
#endif /* CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER */
}
extern void esp_vApplicationTickHook(void);
/**
* @brief Handler of SysTick
*
@@ -176,29 +182,44 @@ BaseType_t xPortSysTickHandler(void)
traceISR_ENTER(SYSTICK_INTR_ID);
// Call IDF Tick Hook
extern void esp_vApplicationTickHook(void);
esp_vApplicationTickHook();
// Call FreeRTOS Increment tick function
BaseType_t xSwitchRequired;
#if CONFIG_FREERTOS_SMP
// Amazon SMP FreeRTOS requires that only core 0 calls xTaskIncrementTick()
#if ( configNUM_CORES > 1 )
if (portGET_CORE_ID() == 0) {
xSwitchRequired = xTaskIncrementTick();
} else {
xSwitchRequired = pdFALSE;
}
#else /* configNUM_CORES > 1 */
xSwitchRequired = xTaskIncrementTick();
#endif /* configNUM_CORES > 1 */
#else /* !CONFIG_FREERTOS_SMP */
#if ( configNUM_CORES > 1 )
/*
For SMP, xTaskIncrementTick() will internally enter a critical section. But only core 0 calls xTaskIncrementTick()
while core 1 should call xTaskIncrementTickOtherCores().
Multi-core IDF FreeRTOS requires that...
- core 0 calls xTaskIncrementTick()
- core 1 calls xTaskIncrementTickOtherCores()
*/
if (xPortGetCoreID() == 0) {
xSwitchRequired = xTaskIncrementTick();
} else {
xSwitchRequired = xTaskIncrementTickOtherCores();
}
#else // configNUM_CORES > 1
#else /* configNUM_CORES > 1 */
/*
Vanilla (single core) FreeRTOS expects that xTaskIncrementTick() cannot be interrupted (i.e., no nested interrupts).
Thus we have to disable interrupts before calling it.
Vanilla (single core) FreeRTOS expects that xTaskIncrementTick() cannot be interrupted (i.e., no nested
interrupts). Thus we have to disable interrupts before calling it.
*/
UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
xSwitchRequired = xTaskIncrementTick();
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
#endif
#endif /* configNUM_CORES > 1 */
#endif /* !CONFIG_FREERTOS_SMP */
// Check if yield is required
if (xSwitchRequired != pdFALSE) {