kopia lustrzana https://github.com/espressif/esp-idf
freertos(esp32s3): SysTick uses systimer
rodzic
b5f9149399
commit
29f581fc70
|
@ -151,16 +151,17 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
|
||||||
// The lowest RAM address used for IDs (pointers)
|
// The lowest RAM address used for IDs (pointers)
|
||||||
#define SYSVIEW_RAM_BASE (SOC_DROM_LOW)
|
#define SYSVIEW_RAM_BASE (SOC_DROM_LOW)
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
|
#ifdef CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER
|
||||||
#if CONFIG_FREERTOS_CORETIMER_0
|
#if CONFIG_FREERTOS_CORETIMER_0
|
||||||
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER0_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
|
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER0_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_FREERTOS_CORETIMER_1
|
#if CONFIG_FREERTOS_CORETIMER_1
|
||||||
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER1_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
|
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER1_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
|
||||||
#endif
|
#endif
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
|
||||||
#define SYSTICK_INTR_ID (ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
|
#elif CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
|
||||||
#endif
|
#define SYSTICK_INTR_ID (ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE)
|
||||||
|
#endif // CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER
|
||||||
|
|
||||||
// SystemView is single core specific: it implies that SEGGER_SYSVIEW_LOCK()
|
// SystemView is single core specific: it implies that SEGGER_SYSVIEW_LOCK()
|
||||||
// disables IRQs (disables rescheduling globally). So we can not use finite timeouts for locks and return error
|
// disables IRQs (disables rescheduling globally). So we can not use finite timeouts for locks and return error
|
||||||
|
|
|
@ -854,7 +854,7 @@ static void reset_task(void* arg)
|
||||||
ESP_LOGI(TAG, "Start reset task");
|
ESP_LOGI(TAG, "Start reset task");
|
||||||
while (!cmd_stop_reset_task) {
|
while (!cmd_stop_reset_task) {
|
||||||
esp_efuse_utility_reset();
|
esp_efuse_utility_reset();
|
||||||
vTaskDelay(1);
|
vTaskDelay(2);
|
||||||
}
|
}
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#if __XTENSA__
|
#if CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
#include "freertos/xtensa_timer.h"
|
#include "freertos/xtensa_timer.h"
|
||||||
#include "xtensa/core-macros.h"
|
#include "xtensa/core-macros.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
|
|
||||||
#define MHZ (1000000)
|
#define MHZ (1000000)
|
||||||
|
|
||||||
#if __XTENSA__
|
#ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
/* CCOMPARE update timeout, in CPU cycles. Any value above ~600 cycles will work
|
/* CCOMPARE update timeout, in CPU cycles. Any value above ~600 cycles will work
|
||||||
* for the purpose of detecting a deadlock.
|
* for the purpose of detecting a deadlock.
|
||||||
*/
|
*/
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
* than this. This is to prevent setting CCOMPARE below CCOUNT.
|
* than this. This is to prevent setting CCOMPARE below CCOUNT.
|
||||||
*/
|
*/
|
||||||
#define CCOMPARE_MIN_CYCLES_IN_FUTURE 1000
|
#define CCOMPARE_MIN_CYCLES_IN_FUTURE 1000
|
||||||
#endif
|
#endif // CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
|
|
||||||
/* When light sleep is used, wake this number of microseconds earlier than
|
/* When light sleep is used, wake this number of microseconds earlier than
|
||||||
* the next tick.
|
* the next tick.
|
||||||
|
@ -184,7 +184,7 @@ static const char* s_mode_names[] = {
|
||||||
};
|
};
|
||||||
#endif // WITH_PROFILING
|
#endif // WITH_PROFILING
|
||||||
|
|
||||||
#if __XTENSA__
|
#ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
/* Indicates to the ISR hook that CCOMPARE needs to be updated on the given CPU.
|
/* Indicates to the ISR hook that CCOMPARE needs to be updated on the given CPU.
|
||||||
* Used in conjunction with cross-core interrupt to update CCOMPARE on the other CPU.
|
* Used in conjunction with cross-core interrupt to update CCOMPARE on the other CPU.
|
||||||
*/
|
*/
|
||||||
|
@ -197,7 +197,7 @@ static uint32_t s_ccount_div;
|
||||||
static uint32_t s_ccount_mul;
|
static uint32_t s_ccount_mul;
|
||||||
|
|
||||||
static void update_ccompare(void);
|
static void update_ccompare(void);
|
||||||
#endif // __XTENSA__
|
#endif // CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
|
|
||||||
static const char* TAG = "pm";
|
static const char* TAG = "pm";
|
||||||
|
|
||||||
|
@ -425,7 +425,7 @@ static void IRAM_ATTR on_freq_update(uint32_t old_ticks_per_us, uint32_t ticks_p
|
||||||
esp_timer_private_update_apb_freq(apb_ticks_per_us);
|
esp_timer_private_update_apb_freq(apb_ticks_per_us);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __XTENSA__
|
#ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
#ifdef XT_RTOS_TIMER_INT
|
#ifdef XT_RTOS_TIMER_INT
|
||||||
/* Calculate new tick divisor */
|
/* Calculate new tick divisor */
|
||||||
_xt_tick_divisor = ticks_per_us * MHZ / XT_TICK_PER_SEC;
|
_xt_tick_divisor = ticks_per_us * MHZ / XT_TICK_PER_SEC;
|
||||||
|
@ -462,7 +462,7 @@ static void IRAM_ATTR on_freq_update(uint32_t old_ticks_per_us, uint32_t ticks_p
|
||||||
s_ccount_div = 0;
|
s_ccount_div = 0;
|
||||||
ESP_PM_TRACE_EXIT(CCOMPARE_UPDATE, core_id);
|
ESP_PM_TRACE_EXIT(CCOMPARE_UPDATE, core_id);
|
||||||
}
|
}
|
||||||
#endif // __XTENSA__
|
#endif // CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -484,7 +484,7 @@ static void IRAM_ATTR do_switch(pm_mode_t new_mode)
|
||||||
portEXIT_CRITICAL_ISR(&s_switch_lock);
|
portEXIT_CRITICAL_ISR(&s_switch_lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if __XTENSA__
|
#ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
if (s_need_update_ccompare[core_id]) {
|
if (s_need_update_ccompare[core_id]) {
|
||||||
s_need_update_ccompare[core_id] = false;
|
s_need_update_ccompare[core_id] = false;
|
||||||
}
|
}
|
||||||
|
@ -529,7 +529,7 @@ static void IRAM_ATTR do_switch(pm_mode_t new_mode)
|
||||||
portEXIT_CRITICAL_ISR(&s_switch_lock);
|
portEXIT_CRITICAL_ISR(&s_switch_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __XTENSA__
|
#ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
/**
|
/**
|
||||||
* @brief Calculate new CCOMPARE value based on s_ccount_{mul,div}
|
* @brief Calculate new CCOMPARE value based on s_ccount_{mul,div}
|
||||||
*
|
*
|
||||||
|
@ -550,7 +550,7 @@ static void IRAM_ATTR update_ccompare(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // __XTENSA__
|
#endif // CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
|
|
||||||
static void IRAM_ATTR leave_idle(void)
|
static void IRAM_ATTR leave_idle(void)
|
||||||
{
|
{
|
||||||
|
@ -656,7 +656,7 @@ void IRAM_ATTR vApplicationSleep( TickType_t xExpectedIdleTime )
|
||||||
/* Adjust RTOS tick count based on the amount of time spent in sleep */
|
/* Adjust RTOS tick count based on the amount of time spent in sleep */
|
||||||
vTaskStepTick(slept_ticks);
|
vTaskStepTick(slept_ticks);
|
||||||
|
|
||||||
#if __XTENSA__
|
#ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
/* Trigger tick interrupt, since sleep time was longer
|
/* Trigger tick interrupt, since sleep time was longer
|
||||||
* than portTICK_PERIOD_MS. Note that setting INTSET does not
|
* than portTICK_PERIOD_MS. Note that setting INTSET does not
|
||||||
* work for timer interrupt, and changing CCOMPARE would clear
|
* work for timer interrupt, and changing CCOMPARE would clear
|
||||||
|
@ -666,7 +666,7 @@ void IRAM_ATTR vApplicationSleep( TickType_t xExpectedIdleTime )
|
||||||
while (!(XTHAL_GET_INTERRUPT() & BIT(XT_TIMER_INTNUM))) {
|
while (!(XTHAL_GET_INTERRUPT() & BIT(XT_TIMER_INTNUM))) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
#elif __riscv
|
#else
|
||||||
portYIELD_WITHIN_API();
|
portYIELD_WITHIN_API();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -810,7 +810,7 @@ void IRAM_ATTR esp_pm_impl_isr_hook(void)
|
||||||
* from happening in this section, since they will also call into esp_pm_impl_isr_hook.
|
* from happening in this section, since they will also call into esp_pm_impl_isr_hook.
|
||||||
*/
|
*/
|
||||||
uint32_t state = portENTER_CRITICAL_NESTED();
|
uint32_t state = portENTER_CRITICAL_NESTED();
|
||||||
#if __XTENSA__ && (portNUM_PROCESSORS == 2)
|
#if defined(CONFIG_FREERTOS_SYSTICK_USES_CCOUNT) && (portNUM_PROCESSORS == 2)
|
||||||
if (s_need_update_ccompare[core_id]) {
|
if (s_need_update_ccompare[core_id]) {
|
||||||
update_ccompare();
|
update_ccompare();
|
||||||
s_need_update_ccompare[core_id] = false;
|
s_need_update_ccompare[core_id] = false;
|
||||||
|
@ -819,7 +819,7 @@ void IRAM_ATTR esp_pm_impl_isr_hook(void)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
leave_idle();
|
leave_idle();
|
||||||
#endif // portNUM_PROCESSORS == 2
|
#endif // CONFIG_FREERTOS_SYSTICK_USES_CCOUNT && portNUM_PROCESSORS == 2
|
||||||
portEXIT_CRITICAL_NESTED(state);
|
portEXIT_CRITICAL_NESTED(state);
|
||||||
ESP_PM_TRACE_EXIT(ISR_HOOK, core_id);
|
ESP_PM_TRACE_EXIT(ISR_HOOK, core_id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ void IRAM_ATTR esp_restart_noos(void)
|
||||||
|
|
||||||
// Reset timer/spi/uart
|
// Reset timer/spi/uart
|
||||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG,
|
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG,
|
||||||
SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST);
|
SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST | SYSTEM_SYSTIMER_RST);
|
||||||
REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0);
|
REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0);
|
||||||
// Reset dma
|
// Reset dma
|
||||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
|
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
|
||||||
|
|
|
@ -94,7 +94,7 @@ void IRAM_ATTR esp_restart_noos(void)
|
||||||
|
|
||||||
// Reset timer/spi/uart
|
// Reset timer/spi/uart
|
||||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG,
|
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG,
|
||||||
SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST);
|
SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST | SYSTEM_SYSTIMER_RST);
|
||||||
REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0);
|
REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0);
|
||||||
// Reset dma
|
// Reset dma
|
||||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
|
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
|
||||||
|
|
|
@ -103,7 +103,7 @@ void IRAM_ATTR esp_restart_noos(void)
|
||||||
|
|
||||||
// Reset timer/spi/uart
|
// Reset timer/spi/uart
|
||||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG,
|
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG,
|
||||||
SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST);
|
SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST | SYSTEM_SYSTIMER_RST);
|
||||||
REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0);
|
REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0);
|
||||||
|
|
||||||
// Reset dma
|
// Reset dma
|
||||||
|
|
|
@ -133,7 +133,7 @@ esp_err_t esp_timer_impl_init(intr_handler_t alarm_handler)
|
||||||
&timer_alarm_isr, NULL, &s_timer_interrupt_handle);
|
&timer_alarm_isr, NULL, &s_timer_interrupt_handle);
|
||||||
|
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
ESP_EARLY_LOGE(TAG, "esp_intr_alloc failed (%#x)", err);
|
ESP_EARLY_LOGE(TAG, "esp_intr_alloc failed (0x%x)", err);
|
||||||
goto err_intr_alloc;
|
goto err_intr_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ esp_err_t esp_timer_impl_init(intr_handler_t alarm_handler)
|
||||||
|
|
||||||
err = esp_intr_enable(s_timer_interrupt_handle);
|
err = esp_intr_enable(s_timer_interrupt_handle);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
ESP_EARLY_LOGE(TAG, "esp_intr_enable failed (%#x)", err);
|
ESP_EARLY_LOGE(TAG, "esp_intr_enable failed (0x%x)", err);
|
||||||
goto err_intr_en;
|
goto err_intr_en;
|
||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
|
|
@ -6,8 +6,7 @@ endif()
|
||||||
|
|
||||||
idf_build_get_property(target IDF_TARGET)
|
idf_build_get_property(target IDF_TARGET)
|
||||||
|
|
||||||
# should test arch here not target, TODO ESP32-C3 IDF-1754
|
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
|
||||||
if(NOT "${target}" STREQUAL "esp32c3" AND NOT "${target}" STREQUAL "esp32h2")
|
|
||||||
set(srcs
|
set(srcs
|
||||||
"port/xtensa/port.c"
|
"port/xtensa/port.c"
|
||||||
"port/xtensa/portasm.S"
|
"port/xtensa/portasm.S"
|
||||||
|
@ -25,10 +24,10 @@ if(NOT "${target}" STREQUAL "esp32c3" AND NOT "${target}" STREQUAL "esp32h2")
|
||||||
include/freertos
|
include/freertos
|
||||||
port/xtensa/include/freertos
|
port/xtensa/include/freertos
|
||||||
port/xtensa
|
port/xtensa
|
||||||
|
port/priv_include
|
||||||
.)
|
.)
|
||||||
|
|
||||||
set(required_components app_trace esp_timer)
|
elseif(CONFIG_IDF_TARGET_ARCH_RISCV)
|
||||||
else() # RISC-V
|
|
||||||
set(srcs
|
set(srcs
|
||||||
"port/riscv/port.c"
|
"port/riscv/port.c"
|
||||||
"port/riscv/portasm.S")
|
"port/riscv/portasm.S")
|
||||||
|
@ -41,13 +40,14 @@ else() # RISC-V
|
||||||
include/freertos
|
include/freertos
|
||||||
port/riscv/include/freertos
|
port/riscv/include/freertos
|
||||||
port/riscv
|
port/riscv
|
||||||
|
port/priv_include
|
||||||
.)
|
.)
|
||||||
|
|
||||||
set(required_components app_trace esp_timer)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND srcs
|
list(APPEND srcs
|
||||||
"port/port_common.c"
|
"port/port_common.c"
|
||||||
|
"port/port_systick.c"
|
||||||
"croutine.c"
|
"croutine.c"
|
||||||
"event_groups.c"
|
"event_groups.c"
|
||||||
"list.c"
|
"list.c"
|
||||||
|
@ -62,8 +62,11 @@ if(CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY)
|
||||||
list(APPEND srcs "port/xtensa/xtensa_loadstore_handler.S")
|
list(APPEND srcs "port/xtensa/xtensa_loadstore_handler.S")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# esp_timer is required by FreeRTOS because we use esp_tiemr_get_time() to do profiling
|
||||||
# app_trace is required by FreeRTOS headers only when CONFIG_APPTRACE_SV_ENABLE=y,
|
# app_trace is required by FreeRTOS headers only when CONFIG_APPTRACE_SV_ENABLE=y,
|
||||||
# but requirements can't depend on config options, so always require it.
|
# REQUIRES can't depend on config options, so always require it.
|
||||||
|
set(required_components app_trace esp_timer)
|
||||||
|
|
||||||
idf_component_register(SRCS "${srcs}"
|
idf_component_register(SRCS "${srcs}"
|
||||||
INCLUDE_DIRS ${include_dirs}
|
INCLUDE_DIRS ${include_dirs}
|
||||||
PRIV_INCLUDE_DIRS ${private_include_dirs}
|
PRIV_INCLUDE_DIRS ${private_include_dirs}
|
||||||
|
|
|
@ -18,9 +18,23 @@ menu "FreeRTOS"
|
||||||
hex
|
hex
|
||||||
default 0x7FFFFFFF
|
default 0x7FFFFFFF
|
||||||
|
|
||||||
|
config FREERTOS_TICK_SUPPORT_CORETIMER
|
||||||
|
bool
|
||||||
|
default y if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2
|
||||||
|
|
||||||
|
config FREERTOS_TICK_SUPPORT_SYSTIMER
|
||||||
|
bool
|
||||||
|
default y if !FREERTOS_TICK_SUPPORT_CORETIMER
|
||||||
|
# ESP32-S3, ESP32-C3 and ESP32-H2 can use Systimer for FreeRTOS SysTick
|
||||||
|
# ESP32S2 also has SYSTIMER but it can not be used for the FreeRTOS SysTick because:
|
||||||
|
# - It has only one counter, which already in use esp_timer.
|
||||||
|
# A counter for SysTick should be stall in debug mode but work esp_timer.
|
||||||
|
# - It is not possible to allocate two handlers for esp_timer and SysTick.
|
||||||
|
|
||||||
choice FREERTOS_CORETIMER
|
choice FREERTOS_CORETIMER
|
||||||
prompt "Xtensa timer to use as the FreeRTOS tick source"
|
prompt "Xtensa timer to use as the FreeRTOS tick source"
|
||||||
default FREERTOS_CORETIMER_0
|
default FREERTOS_CORETIMER_0 if FREERTOS_TICK_SUPPORT_CORETIMER
|
||||||
|
default FREERTOS_CORETIMER_SYSTIMER_LVL1 if FREERTOS_TICK_SUPPORT_SYSTIMER
|
||||||
help
|
help
|
||||||
FreeRTOS needs a timer with an associated interrupt to use as
|
FreeRTOS needs a timer with an associated interrupt to use as
|
||||||
the main tick source to increase counters, run timers and do
|
the main tick source to increase counters, run timers and do
|
||||||
|
@ -29,16 +43,38 @@ menu "FreeRTOS"
|
||||||
|
|
||||||
config FREERTOS_CORETIMER_0
|
config FREERTOS_CORETIMER_0
|
||||||
bool "Timer 0 (int 6, level 1)"
|
bool "Timer 0 (int 6, level 1)"
|
||||||
|
depends on FREERTOS_TICK_SUPPORT_CORETIMER
|
||||||
help
|
help
|
||||||
Select this to use timer 0
|
Select this to use timer 0
|
||||||
|
|
||||||
config FREERTOS_CORETIMER_1
|
config FREERTOS_CORETIMER_1
|
||||||
bool "Timer 1 (int 15, level 3)"
|
bool "Timer 1 (int 15, level 3)"
|
||||||
|
depends on FREERTOS_TICK_SUPPORT_CORETIMER
|
||||||
help
|
help
|
||||||
Select this to use timer 1
|
Select this to use timer 1
|
||||||
|
|
||||||
|
config FREERTOS_CORETIMER_SYSTIMER_LVL1
|
||||||
|
bool "SYSTIMER 0 (level 1)"
|
||||||
|
depends on FREERTOS_TICK_SUPPORT_SYSTIMER
|
||||||
|
help
|
||||||
|
Select this to use systimer with the 1 interrupt priority.
|
||||||
|
|
||||||
|
config FREERTOS_CORETIMER_SYSTIMER_LVL3
|
||||||
|
bool "SYSTIMER 0 (level 3)"
|
||||||
|
depends on FREERTOS_TICK_SUPPORT_SYSTIMER
|
||||||
|
help
|
||||||
|
Select this to use systimer with the 3 interrupt priority.
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
config FREERTOS_SYSTICK_USES_SYSTIMER
|
||||||
|
bool
|
||||||
|
default y if FREERTOS_CORETIMER_SYSTIMER_LVL1 || FREERTOS_CORETIMER_SYSTIMER_LVL3
|
||||||
|
|
||||||
|
config FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
|
bool
|
||||||
|
default y if FREERTOS_CORETIMER_0 || FREERTOS_CORETIMER_1
|
||||||
|
|
||||||
config FREERTOS_OPTIMIZED_SCHEDULER
|
config FREERTOS_OPTIMIZED_SCHEDULER
|
||||||
bool "Enable FreeRTOS pĺatform optimized scheduler"
|
bool "Enable FreeRTOS pĺatform optimized scheduler"
|
||||||
depends on FREERTOS_UNICORE
|
depends on FREERTOS_UNICORE
|
||||||
|
@ -343,6 +379,7 @@ menu "FreeRTOS"
|
||||||
|
|
||||||
config FREERTOS_RUN_TIME_STATS_USING_CPU_CLK
|
config FREERTOS_RUN_TIME_STATS_USING_CPU_CLK
|
||||||
bool "Use CPU Clock for run time stats"
|
bool "Use CPU Clock for run time stats"
|
||||||
|
depends on FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
help
|
help
|
||||||
CPU Clock will be used as the clock source for the generation of run
|
CPU Clock will be used as the clock source for the generation of run
|
||||||
time stats. The CPU Clock has a frequency dependent on
|
time stats. The CPU Clock has a frequency dependent on
|
||||||
|
|
|
@ -7,7 +7,7 @@ ifdef CONFIG_FREERTOS_DEBUG_OCDAWARE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
COMPONENT_ADD_INCLUDEDIRS := include port/xtensa/include
|
COMPONENT_ADD_INCLUDEDIRS := include port/xtensa/include
|
||||||
COMPONENT_PRIV_INCLUDEDIRS := include/freertos port/xtensa/include/freertos port/xtensa .
|
COMPONENT_PRIV_INCLUDEDIRS := include/freertos port/xtensa/include/freertos port/xtensa port/priv_include .
|
||||||
COMPONENT_SRCDIRS += port port/xtensa
|
COMPONENT_SRCDIRS += port port/xtensa
|
||||||
|
|
||||||
ifndef CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY
|
ifndef CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY
|
||||||
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "soc/cpu.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "esp_intr_alloc.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
void SysTickIsrHandler(void *arg);
|
||||||
|
|
||||||
|
#ifdef CONFIG_FREERTOS_UNICORE
|
||||||
|
static uint32_t s_handled_systicks[1] = { 0 };
|
||||||
|
#else
|
||||||
|
static uint32_t s_handled_systicks[2] = { 0 };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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
|
||||||
|
#ifdef CONFIG_FREERTOS_UNICORE
|
||||||
|
const unsigned max_cpu = 1;
|
||||||
|
#else
|
||||||
|
const unsigned max_cpu = 2;
|
||||||
|
#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 < max_cpu; ++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);
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} 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
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handler of SysTick
|
||||||
|
*
|
||||||
|
* The function is called from:
|
||||||
|
* - _frxt_timer_int for xtensa with CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
|
* - SysTickIsrHandler for xtensa with CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
|
||||||
|
* - SysTickIsrHandler for riscv
|
||||||
|
*/
|
||||||
|
BaseType_t xPortSysTickHandler(void)
|
||||||
|
{
|
||||||
|
portbenchmarkIntLatency();
|
||||||
|
traceISR_ENTER(SYSTICK_INTR_ID);
|
||||||
|
BaseType_t ret = xTaskIncrementTick();
|
||||||
|
if(ret != pdFALSE) {
|
||||||
|
portYIELD_FROM_ISR();
|
||||||
|
} else {
|
||||||
|
traceISR_EXIT();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set up the SysTick interrupt
|
||||||
|
*/
|
||||||
|
void vPortSetupTimer(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -91,6 +91,7 @@
|
||||||
#include "riscv/riscv_interrupts.h"
|
#include "riscv/riscv_interrupts.h"
|
||||||
#include "riscv/interrupt.h"
|
#include "riscv/interrupt.h"
|
||||||
|
|
||||||
|
#include "port_systick.h"
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include "esp_intr_alloc.h"
|
#include "esp_intr_alloc.h"
|
||||||
#include "esp_private/crosscore_int.h"
|
#include "esp_private/crosscore_int.h"
|
||||||
|
@ -115,8 +116,6 @@ StackType_t *xIsrStackTop = &xIsrStack[0] + (configISR_STACK_SIZE & (~((portPOIN
|
||||||
|
|
||||||
static const char *TAG = "cpu_start"; // [refactor-todo]: might be appropriate to change in the future, but
|
static const char *TAG = "cpu_start"; // [refactor-todo]: might be appropriate to change in the future, but
|
||||||
|
|
||||||
static void vPortSysTickHandler(void *arg);
|
|
||||||
static void vPortSetupTimer(void);
|
|
||||||
static void prvTaskExitError(void);
|
static void prvTaskExitError(void);
|
||||||
|
|
||||||
extern void esprv_intc_int_set_threshold(int); // FIXME, this function is in ROM only
|
extern void esprv_intc_int_set_threshold(int); // FIXME, this function is in ROM only
|
||||||
|
@ -141,27 +140,6 @@ void vPortExitCritical(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set up the systimer peripheral to generate the tick interrupt
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void vPortSetupTimer(void)
|
|
||||||
{
|
|
||||||
/* 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, ESP_INTR_FLAG_IRAM, vPortSysTickHandler, &systimer_hal, NULL));
|
|
||||||
|
|
||||||
/* configure the timer */
|
|
||||||
systimer_hal_init(&systimer_hal);
|
|
||||||
systimer_hal_connect_alarm_counter(&systimer_hal, SYSTIMER_LL_ALARM_OS_TICK_CORE0, SYSTIMER_LL_COUNTER_OS_TICK);
|
|
||||||
systimer_hal_enable_counter(&systimer_hal, SYSTIMER_LL_COUNTER_OS_TICK);
|
|
||||||
systimer_hal_counter_can_stall_by_cpu(&systimer_hal, SYSTIMER_LL_COUNTER_OS_TICK, 0, true);
|
|
||||||
systimer_hal_set_alarm_period(&systimer_hal, SYSTIMER_LL_ALARM_OS_TICK_CORE0, 1000000UL / CONFIG_FREERTOS_HZ);
|
|
||||||
systimer_hal_select_alarm_mode(&systimer_hal, SYSTIMER_LL_ALARM_OS_TICK_CORE0, SYSTIMER_ALARM_MODE_PERIOD);
|
|
||||||
systimer_hal_enable_alarm_int(&systimer_hal, SYSTIMER_LL_ALARM_OS_TICK_CORE0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void prvTaskExitError(void)
|
void prvTaskExitError(void)
|
||||||
{
|
{
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* A function that implements a task must not exit or attempt to return to
|
||||||
|
@ -293,35 +271,13 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC
|
||||||
return (StackType_t *)frame;
|
return (StackType_t *)frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
IRAM_ATTR void vPortSysTickHandler(void *arg)
|
|
||||||
{
|
|
||||||
systimer_hal_context_t *systimer_hal = (systimer_hal_context_t *)arg;
|
|
||||||
|
|
||||||
systimer_ll_clear_alarm_int(systimer_hal->dev, SYSTIMER_LL_ALARM_OS_TICK_CORE0);
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM_TRACE
|
|
||||||
ESP_PM_TRACE_ENTER(TICK, xPortGetCoreID());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!uxSchedulerRunning) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xTaskIncrementTick() != pdFALSE) {
|
|
||||||
vPortYieldFromISR();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM_TRACE
|
|
||||||
ESP_PM_TRACE_EXIT(TICK, xPortGetCoreID());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler(void)
|
BaseType_t xPortStartScheduler(void)
|
||||||
{
|
{
|
||||||
uxInterruptNesting = 0;
|
uxInterruptNesting = 0;
|
||||||
uxCriticalNesting = 0;
|
uxCriticalNesting = 0;
|
||||||
uxSchedulerRunning = 0;
|
uxSchedulerRunning = 0;
|
||||||
|
|
||||||
|
/* Setup the hardware to generate the tick. */
|
||||||
vPortSetupTimer();
|
vPortSetupTimer();
|
||||||
|
|
||||||
esprv_intc_int_set_threshold(1); /* set global INTC masking level */
|
esprv_intc_int_set_threshold(1); /* set global INTC masking level */
|
||||||
|
|
|
@ -50,6 +50,7 @@ Should be included by all Xtensa generic and RTOS port-specific sources.
|
||||||
|
|
||||||
#include <xtensa/corebits.h>
|
#include <xtensa/corebits.h>
|
||||||
#include <xtensa/config/system.h>
|
#include <xtensa/config/system.h>
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Include any RTOS specific definitions that are needed by this header.
|
Include any RTOS specific definitions that are needed by this header.
|
||||||
|
@ -145,7 +146,9 @@ May be coded in or called from C or assembly, per ABI conventions.
|
||||||
RTOS may optionally define XT_TICK_PER_SEC in its own way (eg. macro).
|
RTOS may optionally define XT_TICK_PER_SEC in its own way (eg. macro).
|
||||||
*/
|
*/
|
||||||
// void XT_RTOS_TIMER_INT(void)
|
// void XT_RTOS_TIMER_INT(void)
|
||||||
|
#ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
#define XT_RTOS_TIMER_INT _frxt_timer_int
|
#define XT_RTOS_TIMER_INT _frxt_timer_int
|
||||||
|
#endif
|
||||||
#define XT_TICK_PER_SEC configTICK_RATE_HZ
|
#define XT_TICK_PER_SEC configTICK_RATE_HZ
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -130,25 +130,16 @@
|
||||||
#include "esp32s3/spiram.h"
|
#include "esp32s3/spiram.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "port_systick.h"
|
||||||
#include "esp_private/startup_internal.h" // [refactor-todo] for g_spiram_ok
|
#include "esp_private/startup_internal.h" // [refactor-todo] for g_spiram_ok
|
||||||
#include "esp_app_trace.h" // [refactor-todo] for esp_app_trace_init
|
#include "esp_app_trace.h" // [refactor-todo] for esp_app_trace_init
|
||||||
|
|
||||||
/* Defined in portasm.h */
|
|
||||||
extern void _frxt_tick_timer_init(void);
|
|
||||||
|
|
||||||
/* Defined in xtensa_context.S */
|
/* Defined in xtensa_context.S */
|
||||||
extern void _xt_coproc_init(void);
|
extern void _xt_coproc_init(void);
|
||||||
|
|
||||||
static const char* TAG = "cpu_start"; // [refactor-todo]: might be appropriate to change in the future, but
|
static const char* TAG = "cpu_start"; // [refactor-todo]: might be appropriate to change in the future, but
|
||||||
// for now maintain the same log output
|
// for now maintain the same log output
|
||||||
|
|
||||||
#if CONFIG_FREERTOS_CORETIMER_0
|
|
||||||
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER0_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
|
|
||||||
#endif
|
|
||||||
#if CONFIG_FREERTOS_CORETIMER_1
|
|
||||||
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER1_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_Static_assert(tskNO_AFFINITY == CONFIG_FREERTOS_NO_AFFINITY, "incorrect tskNO_AFFINITY value");
|
_Static_assert(tskNO_AFFINITY == CONFIG_FREERTOS_NO_AFFINITY, "incorrect tskNO_AFFINITY value");
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -303,11 +294,8 @@ BaseType_t xPortStartScheduler( void )
|
||||||
_xt_coproc_init();
|
_xt_coproc_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Init the tick divisor value */
|
|
||||||
_xt_tick_divisor_init();
|
|
||||||
|
|
||||||
/* Setup the hardware to generate the tick. */
|
/* Setup the hardware to generate the tick. */
|
||||||
_frxt_tick_timer_init();
|
vPortSetupTimer();
|
||||||
|
|
||||||
port_xSchedulerRunning[xPortGetCoreID()] = 1;
|
port_xSchedulerRunning[xPortGetCoreID()] = 1;
|
||||||
|
|
||||||
|
@ -319,23 +307,6 @@ BaseType_t xPortStartScheduler( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortSysTickHandler( void )
|
|
||||||
{
|
|
||||||
BaseType_t ret;
|
|
||||||
|
|
||||||
portbenchmarkIntLatency();
|
|
||||||
traceISR_ENTER(SYSTICK_INTR_ID);
|
|
||||||
ret = xTaskIncrementTick();
|
|
||||||
if( ret != pdFALSE )
|
|
||||||
{
|
|
||||||
portYIELD_FROM_ISR();
|
|
||||||
} else {
|
|
||||||
traceISR_EXIT();
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void vPortYieldOtherCore( BaseType_t coreid ) {
|
void vPortYieldOtherCore( BaseType_t coreid ) {
|
||||||
esp_crosscore_int_send_yield( coreid );
|
esp_crosscore_int_send_yield( coreid );
|
||||||
}
|
}
|
||||||
|
|
|
@ -270,6 +270,7 @@ _frxt_int_exit:
|
||||||
*
|
*
|
||||||
**********************************************************************************************************
|
**********************************************************************************************************
|
||||||
*/
|
*/
|
||||||
|
#ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
.globl _frxt_timer_int
|
.globl _frxt_timer_int
|
||||||
.type _frxt_timer_int,@function
|
.type _frxt_timer_int,@function
|
||||||
.align 4
|
.align 4
|
||||||
|
@ -321,7 +322,7 @@ _frxt_timer_int:
|
||||||
s32i a3, sp, 8
|
s32i a3, sp, 8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Call the FreeRTOS tick handler (see port.c). */
|
/* Call the FreeRTOS tick handler (see port_systick.c). */
|
||||||
#ifdef __XTENSA_CALL0_ABI__
|
#ifdef __XTENSA_CALL0_ABI__
|
||||||
call0 xPortSysTickHandler
|
call0 xPortSysTickHandler
|
||||||
#else
|
#else
|
||||||
|
@ -347,6 +348,7 @@ _frxt_timer_int:
|
||||||
#endif // CONFIG_PM_TRACE
|
#endif // CONFIG_PM_TRACE
|
||||||
|
|
||||||
RET(16)
|
RET(16)
|
||||||
|
#endif // CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
|
|
||||||
/*
|
/*
|
||||||
**********************************************************************************************************
|
**********************************************************************************************************
|
||||||
|
@ -358,6 +360,7 @@ _frxt_timer_int:
|
||||||
*
|
*
|
||||||
**********************************************************************************************************
|
**********************************************************************************************************
|
||||||
*/
|
*/
|
||||||
|
#ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
.globl _frxt_tick_timer_init
|
.globl _frxt_tick_timer_init
|
||||||
.type _frxt_tick_timer_init,@function
|
.type _frxt_tick_timer_init,@function
|
||||||
.align 4
|
.align 4
|
||||||
|
@ -391,6 +394,7 @@ _frxt_tick_timer_init:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RET(16)
|
RET(16)
|
||||||
|
#endif // CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||||
|
|
||||||
/*
|
/*
|
||||||
**********************************************************************************************************
|
**********************************************************************************************************
|
||||||
|
|
|
@ -289,9 +289,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
rsil a3, \level - 1 /* lower interrupt level by 1 */
|
rsil a3, \level - 1 /* lower interrupt level by 1 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef XT_RTOS_TIMER_INT
|
||||||
movi a3, XT_TIMER_INTEN /* a3 = timer interrupt bit */
|
movi a3, XT_TIMER_INTEN /* a3 = timer interrupt bit */
|
||||||
wsr a4, INTCLEAR /* clear sw or edge-triggered interrupt */
|
wsr a4, INTCLEAR /* clear sw or edge-triggered interrupt */
|
||||||
beq a3, a4, 7f /* if timer interrupt then skip table */
|
beq a3, a4, 7f /* if timer interrupt then skip table */
|
||||||
|
#else
|
||||||
|
wsr a4, INTCLEAR /* clear sw or edge-triggered interrupt */
|
||||||
|
#endif // XT_RTOS_TIMER_INT
|
||||||
|
|
||||||
find_ms_setbit a3, a4, a3, 0 /* a3 = interrupt number */
|
find_ms_setbit a3, a4, a3, 0 /* a3 = interrupt number */
|
||||||
|
|
||||||
|
@ -316,6 +320,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
j .L_xt_user_int_&level& /* check for more interrupts */
|
j .L_xt_user_int_&level& /* check for more interrupts */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef XT_RTOS_TIMER_INT
|
||||||
7:
|
7:
|
||||||
|
|
||||||
.ifeq XT_TIMER_INTPRI - \level
|
.ifeq XT_TIMER_INTPRI - \level
|
||||||
|
@ -335,6 +340,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
call4 XT_RTOS_TIMER_INT
|
call4 XT_RTOS_TIMER_INT
|
||||||
#endif
|
#endif
|
||||||
.endif
|
.endif
|
||||||
|
#endif // XT_RTOS_TIMER_INT
|
||||||
|
|
||||||
#ifdef XT_USE_SWPRI
|
#ifdef XT_USE_SWPRI
|
||||||
j 8f
|
j 8f
|
||||||
|
|
|
@ -124,6 +124,11 @@ __attribute__((always_inline)) static inline void systimer_ll_set_alarm_period(s
|
||||||
dev->target_conf[alarm_id].target_period = period;
|
dev->target_conf[alarm_id].target_period = period;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline)) static inline uint32_t systimer_ll_get_alarm_period(systimer_dev_t *dev, uint32_t alarm_id)
|
||||||
|
{
|
||||||
|
return dev->target_conf[alarm_id].target_period;
|
||||||
|
}
|
||||||
|
|
||||||
__attribute__((always_inline)) static inline void systimer_ll_apply_alarm_value(systimer_dev_t *dev, uint32_t alarm_id)
|
__attribute__((always_inline)) static inline void systimer_ll_apply_alarm_value(systimer_dev_t *dev, uint32_t alarm_id)
|
||||||
{
|
{
|
||||||
dev->comp_load[alarm_id].val = 0x01;
|
dev->comp_load[alarm_id].val = 0x01;
|
||||||
|
|
|
@ -124,6 +124,11 @@ __attribute__((always_inline)) static inline void systimer_ll_set_alarm_period(s
|
||||||
dev->target_conf[alarm_id].target_period = period;
|
dev->target_conf[alarm_id].target_period = period;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline)) static inline uint32_t systimer_ll_get_alarm_period(systimer_dev_t *dev, uint32_t alarm_id)
|
||||||
|
{
|
||||||
|
return dev->target_conf[alarm_id].target_period;
|
||||||
|
}
|
||||||
|
|
||||||
__attribute__((always_inline)) static inline void systimer_ll_apply_alarm_value(systimer_dev_t *dev, uint32_t alarm_id)
|
__attribute__((always_inline)) static inline void systimer_ll_apply_alarm_value(systimer_dev_t *dev, uint32_t alarm_id)
|
||||||
{
|
{
|
||||||
dev->comp_load[alarm_id].val = 0x01;
|
dev->comp_load[alarm_id].val = 0x01;
|
||||||
|
|
|
@ -135,6 +135,11 @@ __attribute__((always_inline)) static inline void systimer_ll_set_alarm_period(s
|
||||||
dev->target_conf[alarm_id].target_period = period;
|
dev->target_conf[alarm_id].target_period = period;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline)) static inline uint32_t systimer_ll_get_alarm_period(systimer_dev_t *dev, uint32_t alarm_id)
|
||||||
|
{
|
||||||
|
return dev->target_conf[alarm_id].target_period;
|
||||||
|
}
|
||||||
|
|
||||||
__attribute__((always_inline)) static inline void systimer_ll_apply_alarm_value(systimer_dev_t *dev, uint32_t alarm_id)
|
__attribute__((always_inline)) static inline void systimer_ll_apply_alarm_value(systimer_dev_t *dev, uint32_t alarm_id)
|
||||||
{
|
{
|
||||||
(void)dev;
|
(void)dev;
|
||||||
|
|
|
@ -125,6 +125,11 @@ __attribute__((always_inline)) static inline void systimer_ll_set_alarm_period(s
|
||||||
dev->target_conf[alarm_id].target_period = period;
|
dev->target_conf[alarm_id].target_period = period;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline)) static inline uint32_t systimer_ll_get_alarm_period(systimer_dev_t *dev, uint32_t alarm_id)
|
||||||
|
{
|
||||||
|
return dev->target_conf[alarm_id].target_period;
|
||||||
|
}
|
||||||
|
|
||||||
__attribute__((always_inline)) static inline void systimer_ll_apply_alarm_value(systimer_dev_t *dev, uint32_t alarm_id)
|
__attribute__((always_inline)) static inline void systimer_ll_apply_alarm_value(systimer_dev_t *dev, uint32_t alarm_id)
|
||||||
{
|
{
|
||||||
dev->comp_load[alarm_id].val = 0x01;
|
dev->comp_load[alarm_id].val = 0x01;
|
||||||
|
|
|
@ -251,6 +251,7 @@ static void get_time_task(void *pvParameters)
|
||||||
// although exit flag is set in another task, checking (exit_flag == false) is safe
|
// although exit flag is set in another task, checking (exit_flag == false) is safe
|
||||||
while (exit_flag == false) {
|
while (exit_flag == false) {
|
||||||
gettimeofday(&tv_time, NULL);
|
gettimeofday(&tv_time, NULL);
|
||||||
|
vTaskDelay(1500 / portTICK_PERIOD_MS);
|
||||||
}
|
}
|
||||||
xSemaphoreGive(*sema);
|
xSemaphoreGive(*sema);
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
|
@ -259,13 +260,9 @@ static void get_time_task(void *pvParameters)
|
||||||
static void start_measure(int64_t* sys_time, int64_t* real_time)
|
static void start_measure(int64_t* sys_time, int64_t* real_time)
|
||||||
{
|
{
|
||||||
struct timeval tv_time;
|
struct timeval tv_time;
|
||||||
int64_t t1, t2;
|
// there shouldn't be much time between gettimeofday and esp_timer_get_time
|
||||||
do {
|
gettimeofday(&tv_time, NULL);
|
||||||
t1 = esp_timer_get_time();
|
*real_time = esp_timer_get_time();
|
||||||
gettimeofday(&tv_time, NULL);
|
|
||||||
t2 = esp_timer_get_time();
|
|
||||||
} while (t2 - t1 > 40);
|
|
||||||
*real_time = t2;
|
|
||||||
*sys_time = (int64_t)tv_time.tv_sec * 1000000L + tv_time.tv_usec;
|
*sys_time = (int64_t)tv_time.tv_sec * 1000000L + tv_time.tv_usec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,7 +298,7 @@ static void measure_time_task(void *pvParameters)
|
||||||
int64_t sys_time_us[2] = { main_sys_time_us[0], 0};
|
int64_t sys_time_us[2] = { main_sys_time_us[0], 0};
|
||||||
// although exit flag is set in another task, checking (exit_flag == false) is safe
|
// although exit flag is set in another task, checking (exit_flag == false) is safe
|
||||||
while (exit_flag == false) {
|
while (exit_flag == false) {
|
||||||
esp_rom_delay_us(2 * 1000000); // 2 sec
|
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||||
|
|
||||||
start_measure(&sys_time_us[1], &real_time_us[1]);
|
start_measure(&sys_time_us[1], &real_time_us[1]);
|
||||||
result_adjtime_correction_us[1] += calc_correction("measure", sys_time_us, real_time_us);
|
result_adjtime_correction_us[1] += calc_correction("measure", sys_time_us, real_time_us);
|
||||||
|
@ -322,7 +319,7 @@ static void measure_time_task(void *pvParameters)
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("test time adjustment happens linearly", "[newlib][timeout=35]")
|
TEST_CASE("test time adjustment happens linearly", "[newlib][timeout=15]")
|
||||||
{
|
{
|
||||||
exit_flag = false;
|
exit_flag = false;
|
||||||
|
|
||||||
|
@ -335,8 +332,8 @@ TEST_CASE("test time adjustment happens linearly", "[newlib][timeout=35]")
|
||||||
xTaskCreatePinnedToCore(get_time_task, "get_time_task", 4096, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
|
xTaskCreatePinnedToCore(get_time_task, "get_time_task", 4096, &exit_sema[0], UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
|
||||||
xTaskCreatePinnedToCore(measure_time_task, "measure_time_task", 4096, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
|
xTaskCreatePinnedToCore(measure_time_task, "measure_time_task", 4096, &exit_sema[1], UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
|
||||||
|
|
||||||
printf("start waiting for 30 seconds\n");
|
printf("start waiting for 10 seconds\n");
|
||||||
vTaskDelay(30000 / portTICK_PERIOD_MS);
|
vTaskDelay(10000 / portTICK_PERIOD_MS);
|
||||||
|
|
||||||
// set exit flag to let thread exit
|
// set exit flag to let thread exit
|
||||||
exit_flag = true;
|
exit_flag = true;
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32s3"
|
||||||
|
TEST_COMPONENTS=esp_pm
|
||||||
|
CONFIG_PM_ENABLE=y
|
||||||
|
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
|
Ładowanie…
Reference in New Issue