关于esp32的FreeRTOS

PS:刚开始接触FreeRTOS,先在esp32里面试试水。

本文不做过多的理论解释,只做自己一些初学感悟,如有错误望指出。(后续还会补上stm32里面的RTOS)

学习网站:【ESP32,ESP8266】教程汇总 - DF创客社区 - 分享创造的喜悦 (dfrobot.com.cn)

 之前做项目的时候,发现esp32竟然有两个内核,那就比较强大了喔,可以把函数分在不同的内核里面,这样的话就互相不干扰了。理论上来讲,应该也可以实现两种不同频率的呼吸灯了,但是我的开发板上面没有呼吸灯,所以就不实践了。只能自己写一些简单代码来看看情况了。

1.创建任务,以及删除任务

先来看看代码

void setup()
{
  Serial.begin(115200);
  xTaskCreatePinnedToCore(task1, "task1", 1000, NULL, 1, NULL,0);
  xTaskCreatePinnedToCore(task2, "task2", 1000, NULL, 2, NULL,1);
}

void loop()
{


}

void task1(void *parameter)
{
  while(1)
  {
    Serial.println("task1:hello!");
    vTaskDelay(pdMS_TO_TICKS(1000));
  }
}

void task2(void *parameter)
{
  while(1)
  {
    Serial.println("task2:hello!");
    vTaskDelay(pdMS_TO_TICKS(5000));
  }
}

我们创建了两个任务,分别在两个核上面 运行,其中1是大核,程序默认在1核上面运行的,下面是运行结果

有意思的是,有一个时间段任务1和任务2会同时打印。

我们来看看xTaskCreatePinnedToCore函数的参数

task1:函数指针,指向要运行的任务函数。

"task1":这是任务的名称,是一个字符串,用于标识任务

10000 :这是任务的栈深度,即任务栈的大小,以字为单位

NULL:这是传递给任务函数的参数,可以是一个指针,用于在任务中传递数据,我们这边是空,所以没有参数。

1:标志任务优先级

NULL:这是一个指向 TaskHandle_t类型的指针,用于接收任务句柄。任务句柄可以用于后续操作,如删除任务或挂起任务。待会我们来是一下

0:指在内核0里面运行。

我们来创建一个结构体指针,待会用来作为删除任务的句柄,代码如下。 

TaskHandle_t taskHandle;
void setup()
{
  Serial.begin(115200);
  xTaskCreatePinnedToCore(task1, "task1", 1000, NULL, 1, &taskHandle,0);
  xTaskCreatePinnedToCore(task2, "task2", 1000, NULL, 2, NULL,1);
}

void loop()
{
  delay(10000);
  
}

void task1(void *parameter)
{
    
    for(int i=0;i<20;i++)
    {
      Serial.println("task1:hello!");
      vTaskDelay(pdMS_TO_TICKS(1000));
    }  
    vTaskDelete(taskHandle);
}

void task2(void *parameter)
{
  while(1)
  {
    Serial.println("task2:hello!");
    vTaskDelay(pdMS_TO_TICKS(5000));
  }
}

我们设置在打印20次之后,删除任务1,果然,在20个hello之后task1就不再出现了 

除了这种方式删除任务,还可以直接 vTaskDelete(NULL);可以把本任务函数给删除掉。

void task1(void *parameter)
{
    
    for(int i=0;i<20;i++)
    {
      Serial.println("task1:hello!");
      vTaskDelay(pdMS_TO_TICKS(1000));
    }  
    vTaskDelete(NULL);
}

2.从消息队列里面提取数据

下面是代码和运行结果 

QueueHandle_t myQueue;

typedef struct
{
  unsigned int drain_total_count_p; // 排放总次数
  unsigned int drain_total_pulse_p; // 排放总脉冲
  float last_drain_time_p;          // 前次排水时间
  float drain_total_flow_p;
} jsondata_struct;

jsondata_struct jsondata;
jsondata_struct jsondata_receive;

void setup()
{ 
  Serial.begin(115200);
  myQueue = xQueueCreate(1, sizeof(jsondata_struct)); // 创建队列

  jsondata.drain_total_count_p = 1;
  jsondata.drain_total_pulse_p = 2;
  jsondata.last_drain_time_p = 3.1;
  jsondata.drain_total_flow_p = 3.2;

  xQueueSend(myQueue, &jsondata, portMAX_DELAY); // 发送数据到队列
}

void loop()
{
   BaseType_t messagesWaiting = uxQueueMessagesWaiting(myQueue);
  if(messagesWaiting>0)
  {
    if (xQueueReceive(myQueue, &jsondata_receive, portMAX_DELAY) == pdPASS)
    {
      Serial.printf("数据:%d,%d,%f,%f\n", jsondata_receive.drain_total_count_p, jsondata_receive.drain_total_pulse_p, jsondata_receive.last_drain_time_p, jsondata_receive.drain_total_flow_p);
    }
  }
  else
  {
    Serial.println("无数据");
  }

  delay(2000);
}

 这段代码创建队列,发送数据到队列,然后读取队列里面的数据,需要注意的事,队列的数据只能被读取一次,读完之后就没有数据了。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值