esp_timer: Use Task Notification instead of semaphore

This commit is contained in:
KonstantinKondrashov 2020-10-26 18:07:34 +08:00 committed by bot
parent ea57c10a3c
commit e0d0200aed

View File

@ -22,7 +22,6 @@
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/xtensa_api.h"
#include "soc/spinlock.h"
#include "esp_timer.h"
@ -54,8 +53,6 @@
#define EVENT_ID_DELETE_TIMER 0xF0DE1E1E
#define TIMER_EVENT_QUEUE_SIZE 16
struct esp_timer {
uint64_t alarm;
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);
#endif // WITH_PROFILING
static const char* TAG = "esp_timer";
__attribute__((unused)) static const char* TAG = "esp_timer";
// list of currently armed 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
// task used to dispatch timer callbacks
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
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)
{
while (true){
int res = xSemaphoreTake(s_timer_semaphore, portMAX_DELAY);
assert(res == pdTRUE);
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
// all deferred events are processed at a time
timer_process_alarm(ESP_TIMER_TASK);
}
}
static void IRAM_ATTR timer_alarm_handler(void* arg)
{
int need_yield;
if (xSemaphoreGiveFromISR(s_timer_semaphore, &need_yield) != pdPASS) {
ESP_EARLY_LOGD(TAG, "timer queue overflow");
return;
}
if (need_yield == pdTRUE) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(s_timer_task, &xHigherPriorityTaskWoken);
if (xHigherPriorityTaskWoken == pdTRUE) {
portYIELD_FROM_ISR();
}
}
@ -368,17 +355,6 @@ esp_err_t esp_timer_init(void)
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",
ESP_TASK_TIMER_STACK, NULL, ESP_TASK_TIMER_PRIO, &s_timer_task, PRO_CPU_NUM);
if (ret != pdPASS) {
@ -404,10 +380,7 @@ out:
vTaskDelete(s_timer_task);
s_timer_task = NULL;
}
if (s_timer_semaphore) {
vSemaphoreDelete(s_timer_semaphore);
s_timer_semaphore = NULL;
}
return ESP_ERR_NO_MEM;
}
@ -435,8 +408,6 @@ esp_err_t esp_timer_deinit(void)
vTaskDelete(s_timer_task);
s_timer_task = NULL;
vSemaphoreDelete(s_timer_semaphore);
s_timer_semaphore = NULL;
return ESP_OK;
}