feat(esp_timer): added kconfig option for placing IRAM code into flash

This commit is contained in:
Marius Vikhammer
2025-03-03 14:16:44 +08:00
parent 3fdcf31857
commit 55be8bdc0d
14 changed files with 123 additions and 82 deletions
+21 -21
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -132,7 +132,7 @@ esp_err_t esp_timer_create(const esp_timer_create_args_t* args,
* But actually in IDF esp_timer_restart is used only in one place, which requires keeping
* in IRAM when PM_SLP_IRAM_OPT = y and ESP_TASK_WDT USE ESP_TIMER = y.
*/
esp_err_t IRAM_ATTR esp_timer_restart(esp_timer_handle_t timer, uint64_t timeout_us)
esp_err_t ESP_TIMER_IRAM_ATTR esp_timer_restart(esp_timer_handle_t timer, uint64_t timeout_us)
{
esp_err_t ret = ESP_OK;
@@ -177,7 +177,7 @@ esp_err_t IRAM_ATTR esp_timer_restart(esp_timer_handle_t timer, uint64_t timeout
return ret;
}
esp_err_t IRAM_ATTR esp_timer_start_once(esp_timer_handle_t timer, uint64_t timeout_us)
esp_err_t ESP_TIMER_IRAM_ATTR esp_timer_start_once(esp_timer_handle_t timer, uint64_t timeout_us)
{
if (timer == NULL) {
return ESP_ERR_INVALID_ARG;
@@ -210,7 +210,7 @@ esp_err_t IRAM_ATTR esp_timer_start_once(esp_timer_handle_t timer, uint64_t time
return err;
}
esp_err_t IRAM_ATTR esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t period_us)
esp_err_t ESP_TIMER_IRAM_ATTR esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t period_us)
{
if (timer == NULL) {
return ESP_ERR_INVALID_ARG;
@@ -240,7 +240,7 @@ esp_err_t IRAM_ATTR esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t
return err;
}
esp_err_t IRAM_ATTR esp_timer_stop(esp_timer_handle_t timer)
esp_err_t ESP_TIMER_IRAM_ATTR esp_timer_stop(esp_timer_handle_t timer)
{
if (timer == NULL) {
return ESP_ERR_INVALID_ARG;
@@ -291,7 +291,7 @@ esp_err_t esp_timer_delete(esp_timer_handle_t timer)
return err;
}
static IRAM_ATTR esp_err_t timer_insert(esp_timer_handle_t timer, bool without_update_alarm)
static ESP_TIMER_IRAM_ATTR esp_err_t timer_insert(esp_timer_handle_t timer, bool without_update_alarm)
{
#if WITH_PROFILING
timer_remove_inactive(timer);
@@ -319,7 +319,7 @@ static IRAM_ATTR esp_err_t timer_insert(esp_timer_handle_t timer, bool without_u
return ESP_OK;
}
static IRAM_ATTR esp_err_t timer_remove(esp_timer_handle_t timer)
static ESP_TIMER_IRAM_ATTR esp_err_t timer_remove(esp_timer_handle_t timer)
{
esp_timer_dispatch_t dispatch_method = timer->flags & FL_ISR_DISPATCH_METHOD;
timer_list_lock(dispatch_method);
@@ -344,7 +344,7 @@ static IRAM_ATTR esp_err_t timer_remove(esp_timer_handle_t timer)
#if WITH_PROFILING
static IRAM_ATTR void timer_insert_inactive(esp_timer_handle_t timer)
static ESP_TIMER_IRAM_ATTR void timer_insert_inactive(esp_timer_handle_t timer)
{
/* May be locked or not, depending on where this is called from.
* Lock recursively.
@@ -361,30 +361,30 @@ static IRAM_ATTR void timer_insert_inactive(esp_timer_handle_t timer)
}
}
static IRAM_ATTR void timer_remove_inactive(esp_timer_handle_t timer)
static ESP_TIMER_IRAM_ATTR void timer_remove_inactive(esp_timer_handle_t timer)
{
LIST_REMOVE(timer, list_entry);
}
#endif // WITH_PROFILING
static IRAM_ATTR bool timer_armed(esp_timer_handle_t timer)
static ESP_TIMER_IRAM_ATTR bool timer_armed(esp_timer_handle_t timer)
{
return timer->alarm > 0;
}
static IRAM_ATTR void timer_list_lock(esp_timer_dispatch_t timer_type)
static ESP_TIMER_IRAM_ATTR void timer_list_lock(esp_timer_dispatch_t timer_type)
{
portENTER_CRITICAL_SAFE(&s_timer_lock[timer_type]);
}
static IRAM_ATTR void timer_list_unlock(esp_timer_dispatch_t timer_type)
static ESP_TIMER_IRAM_ATTR void timer_list_unlock(esp_timer_dispatch_t timer_type)
{
portEXIT_CRITICAL_SAFE(&s_timer_lock[timer_type]);
}
#ifdef CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
static IRAM_ATTR bool timer_process_alarm(esp_timer_dispatch_t dispatch_method)
static ESP_TIMER_IRAM_ATTR bool timer_process_alarm(esp_timer_dispatch_t dispatch_method)
#else
static bool timer_process_alarm(esp_timer_dispatch_t dispatch_method)
#endif
@@ -463,14 +463,14 @@ static void timer_task(void* arg)
}
#ifdef CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
IRAM_ATTR void esp_timer_isr_dispatch_need_yield(void)
ESP_TIMER_IRAM_ATTR void esp_timer_isr_dispatch_need_yield(void)
{
assert(xPortInIsrContext());
s_isr_dispatch_need_yield = pdTRUE;
}
#endif
static void IRAM_ATTR timer_alarm_handler(void* arg)
static void ESP_TIMER_IRAM_ATTR timer_alarm_handler(void* arg)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
bool isr_timers_processed = false;
@@ -491,7 +491,7 @@ static void IRAM_ATTR timer_alarm_handler(void* arg)
}
}
static IRAM_ATTR inline bool is_initialized(void)
static ESP_TIMER_IRAM_ATTR inline bool is_initialized(void)
{
return s_timer_task != NULL;
}
@@ -687,7 +687,7 @@ esp_err_t esp_timer_dump(FILE* stream)
return ESP_OK;
}
int64_t IRAM_ATTR esp_timer_get_next_alarm(void)
int64_t ESP_TIMER_IRAM_ATTR esp_timer_get_next_alarm(void)
{
int64_t next_alarm = INT64_MAX;
for (esp_timer_dispatch_t dispatch_method = ESP_TIMER_TASK; dispatch_method < ESP_TIMER_MAX; ++dispatch_method) {
@@ -703,7 +703,7 @@ int64_t IRAM_ATTR esp_timer_get_next_alarm(void)
return next_alarm;
}
int64_t IRAM_ATTR esp_timer_get_next_alarm_for_wake_up(void)
int64_t ESP_TIMER_IRAM_ATTR esp_timer_get_next_alarm_for_wake_up(void)
{
int64_t next_alarm = INT64_MAX;
for (esp_timer_dispatch_t dispatch_method = ESP_TIMER_TASK; dispatch_method < ESP_TIMER_MAX; ++dispatch_method) {
@@ -723,7 +723,7 @@ int64_t IRAM_ATTR esp_timer_get_next_alarm_for_wake_up(void)
return next_alarm;
}
esp_err_t IRAM_ATTR esp_timer_get_period(esp_timer_handle_t timer, uint64_t *period)
esp_err_t ESP_TIMER_IRAM_ATTR esp_timer_get_period(esp_timer_handle_t timer, uint64_t *period)
{
if (timer == NULL || period == NULL) {
return ESP_ERR_INVALID_ARG;
@@ -738,7 +738,7 @@ esp_err_t IRAM_ATTR esp_timer_get_period(esp_timer_handle_t timer, uint64_t *per
return ESP_OK;
}
esp_err_t IRAM_ATTR esp_timer_get_expiry_time(esp_timer_handle_t timer, uint64_t *expiry)
esp_err_t ESP_TIMER_IRAM_ATTR esp_timer_get_expiry_time(esp_timer_handle_t timer, uint64_t *expiry)
{
if (timer == NULL || expiry == NULL) {
return ESP_ERR_INVALID_ARG;
@@ -758,7 +758,7 @@ esp_err_t IRAM_ATTR esp_timer_get_expiry_time(esp_timer_handle_t timer, uint64_t
return ESP_OK;
}
bool IRAM_ATTR esp_timer_is_active(esp_timer_handle_t timer)
bool ESP_TIMER_IRAM_ATTR esp_timer_is_active(esp_timer_handle_t timer)
{
if (timer == NULL) {
return false;
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -32,13 +32,13 @@ void esp_timer_impl_unlock(void)
void esp_timer_private_lock(void) __attribute__((alias("esp_timer_impl_lock")));
void esp_timer_private_unlock(void) __attribute__((alias("esp_timer_impl_unlock")));
void IRAM_ATTR esp_timer_impl_set_alarm(uint64_t timestamp)
void ESP_TIMER_IRAM_ATTR esp_timer_impl_set_alarm(uint64_t timestamp)
{
esp_timer_impl_set_alarm_id(timestamp, 0);
}
#ifdef CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
void IRAM_ATTR esp_timer_impl_try_to_set_next_alarm(void)
void ESP_TIMER_IRAM_ATTR esp_timer_impl_try_to_set_next_alarm(void)
{
portENTER_CRITICAL_ISR(&s_time_update_lock);
unsigned now_alarm_idx; // ISR is called due to this current alarm
@@ -65,7 +65,7 @@ void IRAM_ATTR esp_timer_impl_try_to_set_next_alarm(void)
#endif
/* FIXME: This value is safe for 80MHz APB frequency, should be modified to depend on clock frequency. */
uint64_t IRAM_ATTR esp_timer_impl_get_min_period_us(void)
uint64_t ESP_TIMER_IRAM_ATTR esp_timer_impl_get_min_period_us(void)
{
return 50;
}
+10 -7
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -106,7 +106,7 @@ extern portMUX_TYPE s_time_update_lock;
/* Alarm values to generate interrupt on match */
extern uint64_t timestamp_id[2];
uint64_t IRAM_ATTR esp_timer_impl_get_counter_reg(void)
uint64_t ESP_TIMER_IRAM_ATTR esp_timer_impl_get_counter_reg(void)
{
uint32_t lo, hi;
uint32_t lo_start = REG_READ(COUNT_LO_REG);
@@ -137,14 +137,14 @@ uint64_t IRAM_ATTR esp_timer_impl_get_counter_reg(void)
return result.val;
}
int64_t IRAM_ATTR esp_timer_impl_get_time(void)
int64_t ESP_TIMER_IRAM_ATTR esp_timer_impl_get_time(void)
{
return esp_timer_impl_get_counter_reg() / TICKS_PER_US;
}
int64_t esp_timer_get_time(void) __attribute__((alias("esp_timer_impl_get_time")));
void IRAM_ATTR esp_timer_impl_set_alarm_id(uint64_t timestamp, unsigned alarm_id)
void ESP_TIMER_IRAM_ATTR esp_timer_impl_set_alarm_id(uint64_t timestamp, unsigned alarm_id)
{
assert(alarm_id < sizeof(timestamp_id) / sizeof(timestamp_id[0]));
portENTER_CRITICAL_SAFE(&s_time_update_lock);
@@ -174,7 +174,7 @@ void IRAM_ATTR esp_timer_impl_set_alarm_id(uint64_t timestamp, unsigned alarm_id
portEXIT_CRITICAL_SAFE(&s_time_update_lock);
}
static void IRAM_ATTR timer_alarm_isr(void *arg)
static void ESP_TIMER_IRAM_ATTR timer_alarm_isr(void *arg)
{
#if ISR_HANDLERS == 1
/* Clear interrupt status */
@@ -220,7 +220,7 @@ static void IRAM_ATTR timer_alarm_isr(void *arg)
#endif // ISR_HANDLERS != 1
}
void IRAM_ATTR esp_timer_impl_update_apb_freq(uint32_t apb_ticks_per_us)
void ESP_TIMER_IRAM_ATTR esp_timer_impl_update_apb_freq(uint32_t apb_ticks_per_us)
{
portENTER_CRITICAL_SAFE(&s_time_update_lock);
assert(apb_ticks_per_us >= 3 && "divider value too low");
@@ -278,7 +278,10 @@ esp_err_t esp_timer_impl_init(intr_handler_t alarm_handler)
int isr_flags = ESP_INTR_FLAG_INTRDISABLED
| ((1 << CONFIG_ESP_TIMER_INTERRUPT_LEVEL) & ESP_INTR_FLAG_LEVELMASK)
| ESP_INTR_FLAG_IRAM;
#if CONFIG_ESP_TIMER_IN_IRAM
| ESP_INTR_FLAG_IRAM
#endif
;
esp_err_t err = esp_intr_alloc(INTR_SOURCE_LACT, isr_flags,
&timer_alarm_isr, NULL,
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -60,12 +60,12 @@ extern portMUX_TYPE s_time_update_lock;
/* Alarm values to generate interrupt on match */
extern uint64_t timestamp_id[2];
uint64_t IRAM_ATTR esp_timer_impl_get_counter_reg(void)
uint64_t ESP_TIMER_IRAM_ATTR esp_timer_impl_get_counter_reg(void)
{
return systimer_hal_get_counter_value(&systimer_hal, SYSTIMER_COUNTER_ESPTIMER);
}
int64_t IRAM_ATTR esp_timer_impl_get_time(void)
int64_t ESP_TIMER_IRAM_ATTR esp_timer_impl_get_time(void)
{
// we hope the execution time of this function won't > 1us
// thus, to save one function call, we didn't use the existing `systimer_hal_get_time`
@@ -74,7 +74,7 @@ int64_t IRAM_ATTR esp_timer_impl_get_time(void)
int64_t esp_timer_get_time(void) __attribute__((alias("esp_timer_impl_get_time")));
void IRAM_ATTR esp_timer_impl_set_alarm_id(uint64_t timestamp, unsigned alarm_id)
void ESP_TIMER_IRAM_ATTR esp_timer_impl_set_alarm_id(uint64_t timestamp, unsigned alarm_id)
{
assert(alarm_id < sizeof(timestamp_id) / sizeof(timestamp_id[0]));
portENTER_CRITICAL_SAFE(&s_time_update_lock);
@@ -84,7 +84,7 @@ void IRAM_ATTR esp_timer_impl_set_alarm_id(uint64_t timestamp, unsigned alarm_id
portEXIT_CRITICAL_SAFE(&s_time_update_lock);
}
static void IRAM_ATTR timer_alarm_isr(void *arg)
static void ESP_TIMER_IRAM_ATTR timer_alarm_isr(void *arg)
{
#if ISR_HANDLERS == 1
// clear the interrupt
@@ -129,7 +129,7 @@ static void IRAM_ATTR timer_alarm_isr(void *arg)
#endif // ISR_HANDLERS != 1
}
void IRAM_ATTR esp_timer_impl_update_apb_freq(uint32_t apb_ticks_per_us)
void ESP_TIMER_IRAM_ATTR esp_timer_impl_update_apb_freq(uint32_t apb_ticks_per_us)
{
#if !SOC_SYSTIMER_FIXED_DIVIDER
systimer_hal_on_apb_freq_update(&systimer_hal, apb_ticks_per_us);
@@ -200,7 +200,10 @@ esp_err_t esp_timer_impl_init(intr_handler_t alarm_handler)
#if !SOC_SYSTIMER_INT_LEVEL
| ESP_INTR_FLAG_EDGE
#endif
| ESP_INTR_FLAG_IRAM;
#if CONFIG_ESP_TIMER_IN_IRAM
| ESP_INTR_FLAG_IRAM
#endif
;
esp_err_t err = esp_intr_alloc(ETS_SYSTIMER_TARGET2_INTR_SOURCE, isr_flags,
&timer_alarm_isr, NULL,
+6 -5
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -21,6 +21,7 @@
#include "freertos/semphr.h"
#include "sdkconfig.h"
#include "esp_timer.h"
#include "esp_timer_impl.h"
// for ETSTimer type
#include "rom/ets_sys.h"
@@ -34,7 +35,7 @@
#define TIMER_INITIALIZED_FIELD(p_ets_timer) ((p_ets_timer)->timer_expire)
#define TIMER_INITIALIZED_VAL 0x12121212
static IRAM_ATTR bool timer_initialized(ETSTimer *ptimer)
static ESP_TIMER_IRAM_ATTR bool timer_initialized(ETSTimer *ptimer)
{
return TIMER_INITIALIZED_FIELD(ptimer) == TIMER_INITIALIZED_VAL;
}
@@ -58,7 +59,7 @@ void ets_timer_setfn(ETSTimer *ptimer, ETSTimerFunc *pfunction, void *parg)
}
}
void IRAM_ATTR ets_timer_arm_us(ETSTimer *ptimer, uint32_t time_us, bool repeat_flag)
void ESP_TIMER_IRAM_ATTR ets_timer_arm_us(ETSTimer *ptimer, uint32_t time_us, bool repeat_flag)
{
assert(timer_initialized(ptimer));
esp_timer_stop(ESP_TIMER(ptimer)); // no error check
@@ -69,7 +70,7 @@ void IRAM_ATTR ets_timer_arm_us(ETSTimer *ptimer, uint32_t time_us, bool repeat_
}
}
void IRAM_ATTR ets_timer_arm(ETSTimer *ptimer, uint32_t time_ms, bool repeat_flag)
void ESP_TIMER_IRAM_ATTR ets_timer_arm(ETSTimer *ptimer, uint32_t time_ms, bool repeat_flag)
{
uint64_t time_us = 1000LL * (uint64_t) time_ms;
assert(timer_initialized(ptimer));
@@ -90,7 +91,7 @@ void ets_timer_done(ETSTimer *ptimer)
}
}
void IRAM_ATTR ets_timer_disarm(ETSTimer *ptimer)
void ESP_TIMER_IRAM_ATTR ets_timer_disarm(ETSTimer *ptimer)
{
if (timer_initialized(ptimer)) {
esp_timer_stop(ESP_TIMER(ptimer));
+2 -2
View File
@@ -35,12 +35,12 @@ void esp_timer_impl_init_system_time(void)
#endif
}
int64_t IRAM_ATTR esp_system_get_time(void)
int64_t ESP_TIMER_IRAM_ATTR esp_system_get_time(void)
{
return esp_timer_get_time() + s_correction_us;
}
uint32_t IRAM_ATTR esp_system_get_time_resolution(void)
uint32_t ESP_TIMER_IRAM_ATTR esp_system_get_time_resolution(void)
{
return 1000;
}