ESP32学习笔记:FreeRTOS中的消息队列

#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_log.h"
#include "driver/timer.h"

#define TIMER_DIVIDER         16  
#define TIMER_SCALE           (TIMER_BASE_CLK / TIMER_DIVIDER/ 1000)  //分频
#define TIMER_INTERVAL0_SEC   (1) //计数值,如果为1,则1ms进入中断;如果为10,则10ms进入中断
#define TEST_WITH_RELOAD      1  

typedef struct {
    uint64_t timer_minute_count;
    uint64_t timer_second_count;
} timer_event_t;

timer_event_t g_timer_event;

xQueueHandle timer_queue;


unsigned int timer_counter = 0;

void IRAM_ATTR timer_group0_isr(void *para) //中断函数
{
    timer_spinlock_take(TIMER_GROUP_0);
    int timer_idx = (int) para;

    // /* Prepare basic event data
    //    that will be then sent back to the main program task */
    timer_counter++;
    timer_event_t evt;
    xQueueSendFromISR(timer_queue, &evt, NULL); //每次进入中断都会向设置好的队列发送消息

    timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0);

    /* After the alarm has been triggered
      we need enable it again, so it is triggered the next time */
    timer_group_enable_alarm_in_isr(TIMER_GROUP_0, timer_idx);

    /* Now just send the event data back to the main program task */
    timer_spinlock_give(TIMER_GROUP_0);
}

static void example_tg0_timer_init(int timer_idx,
                                   bool auto_reload, double timer_interval_sec)
{
    /* Select and initialize basic parameters of the timer */
    timer_config_t config = {
        .divider = TIMER_DIVIDER,
        .counter_dir = TIMER_COUNT_UP,
        .counter_en = TIMER_PAUSE,
        .alarm_en = TIMER_ALARM_EN,
        .auto_reload = auto_reload,
    }; // default clock source is APB
    timer_init(TIMER_GROUP_0, timer_idx, &config);

    /* Timer's counter will initially start from value below.
       Also, if auto_reload is set, this value will be automatically reload on alarm */
    timer_set_counter_value(TIMER_GROUP_0, timer_idx, 0x00000000ULL);

    /* Configure the alarm value and the interrupt on alarm. */
    timer_set_alarm_value(TIMER_GROUP_0, timer_idx, timer_interval_sec * TIMER_SCALE);
    timer_enable_intr(TIMER_GROUP_0, timer_idx);
    timer_isr_register(TIMER_GROUP_0, timer_idx, timer_group0_isr,
                       (void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL);

    timer_start(TIMER_GROUP_0, timer_idx);
}

static void timer_example_evt_task(void *arg)
{
    while (1) {
        timer_event_t evt;
        xQueueReceive(timer_queue, &evt, portMAX_DELAY);
        g_timer_event.timer_minute_count ++;
        //60s 计算一次 刷新时间
        if(g_timer_event.timer_minute_count >= 60000){
            g_timer_event.timer_minute_count = 0;
            printf("One minute receive ...\n");
        }
        g_timer_event.timer_second_count ++;
        //1s计算一次
        if(g_timer_event.timer_second_count >= 1000){
            g_timer_event.timer_second_count = 0;
            printf("One second receive ...\n");
        }
    }
}

void ds_timer_init(void)
{
    g_timer_event.timer_minute_count = 0;
    g_timer_event.timer_second_count = 0;
    timer_queue = xQueueCreate(10, sizeof(timer_event_t));
    example_tg0_timer_init(TIMER_0, TEST_WITH_RELOAD, TIMER_INTERVAL0_SEC);
    xTaskCreate(timer_example_evt_task, "timer_evt_task", 2048, NULL, 5, NULL);
}



void app_main(void)
{
    ds_timer_init();

    while(1){
        printf("system run ...\n");
        vTaskDelay(1000 / portTICK_PERIOD_MS);

        if(timer_counter >= 1000)
        {
            timer_counter = 0;
            printf("ESP32 Demo Timer Task run ...\n");
        }
    }
}

       主要是验证了ESP32中的消息队列机制,配置好定时器后,在每次定时中断中向消息队列发送消息,在消息队列接收端接收消息并打印触发信息。作为一个小demo方便后续开发查阅。

运行结果:

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

moon2shine

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值