But in the example of esp-idf, let me use xQueueReceive check in while loop, I think it's not interesting at all. Can I use the code my way?
If you need to use xQueueReceive in a while loop, I saw examples on the website https://embeddedexplorer.com/esp32-timer-tutorial/, use xSemaphoreTake instead, which one is more suitable?
Code: Select all
/*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gptimer.h"
#include "driver/gpio.h"
#include "esp_log.h"
#define LED_PIN GPIO_NUM_9
static const char *TAG = "example";
static int led_state = 0;
typedef struct
{
uint64_t event_count;
} example_queue_element_t;
static bool IRAM_ATTR example_timer_on_alarm_cb_v2(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
{
BaseType_t high_task_awoken = pdFALSE;
QueueHandle_t queue = (QueueHandle_t)user_data;
// Retrieve count value and send to queue
example_queue_element_t ele = {
.event_count = edata->count_value};
if (led_state == 0) // if not suitable I'll move it into the while loop.
{
led_state = 1;
gpio_set_level(LED_PIN, 1);
}
else
{
led_state = 0;
gpio_set_level(LED_PIN, 0);
}
xQueueSendFromISR(queue, &ele, &high_task_awoken);
// return whether we need to yield at the end of ISR
return (high_task_awoken == pdTRUE);
}
void app_main(void)
{
gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);
gpio_set_level(LED_PIN, 0);
example_queue_element_t ele;
QueueHandle_t queue = xQueueCreate(10, sizeof(example_queue_element_t));
if (!queue)
{
ESP_LOGE(TAG, "Creating queue failed");
return;
}
ESP_LOGI(TAG, "Create timer handle");
gptimer_handle_t gptimer = NULL;
gptimer_config_t timer_config = {
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
.direction = GPTIMER_COUNT_UP,
.resolution_hz = 1000000, // 1MHz, 1 tick=1us
};
ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));
// set a new callback function
gptimer_event_callbacks_t cbs = {
.on_alarm = example_timer_on_alarm_cb_v2,
};
// cbs.on_alarm = example_timer_on_alarm_cb_v2;
ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, queue));
ESP_ERROR_CHECK(gptimer_enable(gptimer));
ESP_LOGI(TAG, "Start timer, auto-reload at alarm event");
gptimer_alarm_config_t alarm_config2 = {
.reload_count = 0,
.alarm_count = 1000, // period = 0.001s
.flags.auto_reload_on_alarm = true,
};
ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config2));
ESP_ERROR_CHECK(gptimer_start(gptimer));
printf("Timer Loop \n");
while (1)
{
if (xQueueReceive(queue, &ele, pdMS_TO_TICKS(1000)))
{
}
}
ESP_LOGI(TAG, "Stop timer");
ESP_ERROR_CHECK(gptimer_stop(gptimer));
}