diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c index 686fd0dc59..8f43a25749 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c @@ -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 diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c index a019d823d5..2f39720aca 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c @@ -9,6 +9,7 @@ #include #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 @@ -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 diff --git a/components/freertos/linker_common.lf b/components/freertos/linker_common.lf index 425b10d362..9cc9724346 100644 --- a/components/freertos/linker_common.lf +++ b/components/freertos/linker_common.lf @@ -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) diff --git a/components/freertos/linker_smp.lf b/components/freertos/linker_smp.lf index 10ff708fd9..3ee3613314 100644 --- a/components/freertos/linker_smp.lf +++ b/components/freertos/linker_smp.lf @@ -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) diff --git a/components/freertos/port_systick.c b/components/freertos/port_systick.c index 810f0b535d..789a232090 100644 --- a/components/freertos/port_systick.c +++ b/components/freertos/port_systick.c @@ -4,61 +4,47 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "sdkconfig.h" +#include #include -#include #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 ( configNUM_CORES > 1 ) - /* - For SMP, xTaskIncrementTick() will internally enter a critical section. But only core 0 calls xTaskIncrementTick() - while core 1 should call xTaskIncrementTickOtherCores(). - */ - if (xPortGetCoreID() == 0) { - xSwitchRequired = xTaskIncrementTick(); - } else { - xSwitchRequired = xTaskIncrementTickOtherCores(); - } -#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. - */ - UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - xSwitchRequired = xTaskIncrementTick(); - portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); -#endif + #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 ) + /* + 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 */ + /* + 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 /* configNUM_CORES > 1 */ + #endif /* !CONFIG_FREERTOS_SMP */ // Check if yield is required if (xSwitchRequired != pdFALSE) {