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:
Angus Gratton
2020-11-11 10:50:20 +08:00

View File

@@ -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;
} }