mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-03 20:54:32 +02:00
Merge branch 'feature/esp_timer_task_uses_freertos_notification' into 'master'
esp_timer: Use Task Notification instead of semaphore See merge request espressif/esp-idf!10991
This commit is contained in:
@@ -22,7 +22,6 @@
|
|||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "freertos/semphr.h"
|
|
||||||
#include "freertos/xtensa_api.h"
|
#include "freertos/xtensa_api.h"
|
||||||
#include "soc/spinlock.h"
|
#include "soc/spinlock.h"
|
||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
@@ -54,8 +53,6 @@
|
|||||||
|
|
||||||
#define EVENT_ID_DELETE_TIMER 0xF0DE1E1E
|
#define EVENT_ID_DELETE_TIMER 0xF0DE1E1E
|
||||||
|
|
||||||
#define TIMER_EVENT_QUEUE_SIZE 16
|
|
||||||
|
|
||||||
struct esp_timer {
|
struct esp_timer {
|
||||||
uint64_t alarm;
|
uint64_t alarm;
|
||||||
uint64_t period;
|
uint64_t period;
|
||||||
@@ -85,7 +82,7 @@ static void timer_insert_inactive(esp_timer_handle_t timer);
|
|||||||
static void timer_remove_inactive(esp_timer_handle_t timer);
|
static void timer_remove_inactive(esp_timer_handle_t timer);
|
||||||
#endif // WITH_PROFILING
|
#endif // WITH_PROFILING
|
||||||
|
|
||||||
static const char* TAG = "esp_timer";
|
__attribute__((unused)) static const char* TAG = "esp_timer";
|
||||||
|
|
||||||
// list of currently armed timers
|
// list of currently armed timers
|
||||||
static LIST_HEAD(esp_timer_list, esp_timer) s_timers =
|
static LIST_HEAD(esp_timer_list, esp_timer) s_timers =
|
||||||
@@ -98,13 +95,6 @@ static LIST_HEAD(esp_inactive_timer_list, esp_timer) s_inactive_timers =
|
|||||||
#endif
|
#endif
|
||||||
// task used to dispatch timer callbacks
|
// task used to dispatch timer callbacks
|
||||||
static TaskHandle_t s_timer_task;
|
static TaskHandle_t s_timer_task;
|
||||||
// counting semaphore used to notify the timer task from ISR
|
|
||||||
static SemaphoreHandle_t s_timer_semaphore;
|
|
||||||
|
|
||||||
#if CONFIG_SPIRAM_USE_MALLOC
|
|
||||||
// memory for s_timer_semaphore
|
|
||||||
static StaticQueue_t s_timer_semaphore_memory;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// lock protecting s_timers, s_inactive_timers
|
// lock protecting s_timers, s_inactive_timers
|
||||||
static portMUX_TYPE s_timer_lock = portMUX_INITIALIZER_UNLOCKED;
|
static portMUX_TYPE s_timer_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||||
@@ -338,20 +328,17 @@ static void timer_process_alarm(esp_timer_dispatch_t dispatch_method)
|
|||||||
static void timer_task(void* arg)
|
static void timer_task(void* arg)
|
||||||
{
|
{
|
||||||
while (true){
|
while (true){
|
||||||
int res = xSemaphoreTake(s_timer_semaphore, portMAX_DELAY);
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||||
assert(res == pdTRUE);
|
// all deferred events are processed at a time
|
||||||
timer_process_alarm(ESP_TIMER_TASK);
|
timer_process_alarm(ESP_TIMER_TASK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IRAM_ATTR timer_alarm_handler(void* arg)
|
static void IRAM_ATTR timer_alarm_handler(void* arg)
|
||||||
{
|
{
|
||||||
int need_yield;
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
if (xSemaphoreGiveFromISR(s_timer_semaphore, &need_yield) != pdPASS) {
|
vTaskNotifyGiveFromISR(s_timer_task, &xHigherPriorityTaskWoken);
|
||||||
ESP_EARLY_LOGD(TAG, "timer queue overflow");
|
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (need_yield == pdTRUE) {
|
|
||||||
portYIELD_FROM_ISR();
|
portYIELD_FROM_ISR();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -368,17 +355,6 @@ esp_err_t esp_timer_init(void)
|
|||||||
return ESP_ERR_INVALID_STATE;
|
return ESP_ERR_INVALID_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_SPIRAM_USE_MALLOC
|
|
||||||
memset(&s_timer_semaphore_memory, 0, sizeof(StaticQueue_t));
|
|
||||||
s_timer_semaphore = xSemaphoreCreateCountingStatic(TIMER_EVENT_QUEUE_SIZE, 0, &s_timer_semaphore_memory);
|
|
||||||
#else
|
|
||||||
s_timer_semaphore = xSemaphoreCreateCounting(TIMER_EVENT_QUEUE_SIZE, 0);
|
|
||||||
#endif
|
|
||||||
if (!s_timer_semaphore) {
|
|
||||||
err = ESP_ERR_NO_MEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ret = xTaskCreatePinnedToCore(&timer_task, "esp_timer",
|
int ret = xTaskCreatePinnedToCore(&timer_task, "esp_timer",
|
||||||
ESP_TASK_TIMER_STACK, NULL, ESP_TASK_TIMER_PRIO, &s_timer_task, PRO_CPU_NUM);
|
ESP_TASK_TIMER_STACK, NULL, ESP_TASK_TIMER_PRIO, &s_timer_task, PRO_CPU_NUM);
|
||||||
if (ret != pdPASS) {
|
if (ret != pdPASS) {
|
||||||
@@ -404,10 +380,7 @@ out:
|
|||||||
vTaskDelete(s_timer_task);
|
vTaskDelete(s_timer_task);
|
||||||
s_timer_task = NULL;
|
s_timer_task = NULL;
|
||||||
}
|
}
|
||||||
if (s_timer_semaphore) {
|
|
||||||
vSemaphoreDelete(s_timer_semaphore);
|
|
||||||
s_timer_semaphore = NULL;
|
|
||||||
}
|
|
||||||
return ESP_ERR_NO_MEM;
|
return ESP_ERR_NO_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -435,8 +408,6 @@ esp_err_t esp_timer_deinit(void)
|
|||||||
|
|
||||||
vTaskDelete(s_timer_task);
|
vTaskDelete(s_timer_task);
|
||||||
s_timer_task = NULL;
|
s_timer_task = NULL;
|
||||||
vSemaphoreDelete(s_timer_semaphore);
|
|
||||||
s_timer_semaphore = NULL;
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user