1018|4

504

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

【Beetle ESP32 C6迷你开发板】--4.FreeRTOS任务与消息队列 [复制链接]

      本篇讲述串口接收数据,通过消息队列发送和任务接收消息队列。

一.代码准备

1.串口初始化,主要用来打印串口日志和接收串口数据

 // Initialize serial communication at 115200 bits per second:
  Serial.begin(115200);
  while (!Serial) {
    delay(10);
  }
  Serial.println("Uart Init");
  Serial.println();

2.创建消息队列

// Create the queue which will have <QueueElementSize> number of elements, each of size `message_t` and pass the address to <QueueHandle>.
  QueueHandle = xQueueCreate(QueueElementSize, sizeof(message_t));

  // Check if the queue was successfully created
  if (QueueHandle == NULL) {
    Serial.println("Queue could not be created. Halt.");
    while (1) {
      delay(1000);  // Halt at this point as is not possible to continue
    }
  }
  Serial.println("Create Queue OK");
  Serial.println();

3.创建串口接收及发送消息队列任务


//任务检查串口接收,有数据就消息队列发送出去
void TaskReadFromSerial(void *pvParameters) {  // This is a task.
  message_t message;
  for (;;) {
    // Check if any data are waiting in the Serial buffer
    message.line_length = Serial.available();
    if (message.line_length > 0) {
      // Check if the queue exists AND if there is any free space in the queue
      if (QueueHandle != NULL && uxQueueSpacesAvailable(QueueHandle) > 0) {
        int max_length = message.line_length < MAX_LINE_LENGTH ? message.line_length : MAX_LINE_LENGTH - 1;
        for (int i = 0; i < max_length; ++i) {
          message.line[i] = Serial.read();
        }
        message.line_length = max_length;
        message.line[message.line_length] = 0;  // Add the terminating nul char
        Serial.println("Receive UART data,and go to send message queue");
        Serial.println();
        // The line needs to be passed as pointer to void.
        // The last parameter states how many milliseconds should wait (keep trying to send) if is not possible to send right away.
        // When the wait parameter is 0 it will not wait and if the send is not possible the function will return errQUEUE_FULL
        int ret = xQueueSend(QueueHandle, (void *)&message, 0);
        if (ret == pdTRUE) {
          // The message was successfully sent.
           Serial.println("The message was successfully sent");
        } else if (ret == errQUEUE_FULL) {
          // Since we are checking uxQueueSpacesAvailable this should not occur, however if more than one task should
          //   write into the same queue it can fill-up between the test and actual send attempt
          Serial.println("The `TaskReadFromSerial` was unable to send data into the Queue");
        }  // Queue send check
      }  // Queue sanity check
    } else {
      delay(100);  // Allow other tasks to run when there is nothing to read
    }  // Serial buffer check
  }  // Infinite loop
}



{ 
xTaskCreate(
    TaskReadFromSerial, "Task Read From Serial", 2048  // Stack size
    ,
    NULL  // No parameter is used
    ,
    1  // Priority
    ,
    NULL  // Task handle is not used here
  );
  Serial.println("Create TaskReadFromSerial Task");
  Serial.println();
}

4.创建消息队列接收任务

//消息队接收任务
void TaskWriteToSerial(void *pvParameters) {  // This is a task.
  message_t message;
  for (;;) {  // A Task shall never return or exit.
    // One approach would be to poll the function (uxQueueMessagesWaiting(QueueHandle) and call delay if nothing is waiting.
    // The other approach is to use infinite time to wait defined by constant `portMAX_DELAY`:
    if (QueueHandle != NULL) {  // Sanity check just to make sure the queue actually exists
      int ret = xQueueReceive(QueueHandle, &message, portMAX_DELAY);
      if (ret == pdPASS) {
        // The message was successfully received - send it back to Serial port and "Echo: "
        Serial.printf("The message was successfully received\"\n");
        Serial.printf("Echo line of size %d: \"%s\"\n", message.line_length, message.line);
        // The item is queued by copy, not by reference, so lets free the buffer after use.
      } else if (ret == pdFALSE) {
        Serial.println("The `TaskWriteToSerial` was unable to receive data from the Queue");
      }
    }  // Sanity check
  }  // Infinite loop
}

{
// Set up two tasks to run independently.
  xTaskCreate(
    TaskWriteToSerial, "Task Write To Serial"  // A name just for humans
    ,
    2048  // The stack size can be checked by calling `uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL);`
    ,
    NULL  // No parameter is used
    ,
    2  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,
    NULL  // Task handle is not used here
  );
  Serial.println("Create TaskWriteToSerial Task");
  Serial.println();}

二.编译烧录测验

      编译烧录后可看到初始化情况,在串口发送数据,可看到串口接收并将数据消息队列发送出去,任务接收到消息队列并打印出来,实现了消息队列的成功收发。

图1:任务与消息队列发送与接收

      由此,Beetle ESP32 C6可用FreeRTOS实现系统功能。

此帖出自无线连接论坛

最新回复

最近在用的AZURE_RTOS,就不太会注册,总是失败,要不就不运行,要不就只有它运行   详情 回复 发表于 2024-5-23 09:38
点赞 关注
个人签名

保持热爱

 

回复
举报

6483

帖子

9

TA的资源

版主

沙发
 

FreeRTOS必须要先注册才能使用吗?  

此帖出自无线连接论坛

点评

和平时用的RTOS系统用法一样,创建后使用  详情 回复 发表于 2024-5-22 21:49
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 

回复

504

帖子

0

TA的资源

纯净的硅(初级)

板凳
 
秦天qintian0303 发表于 2024-5-18 11:10 FreeRTOS必须要先注册才能使用吗?  

和平时用的RTOS系统用法一样,创建后使用

此帖出自无线连接论坛

点评

最近在用的AZURE_RTOS,就不太会注册,总是失败,要不就不运行,要不就只有它运行  详情 回复 发表于 2024-5-23 09:38
个人签名

保持热爱

 
 
 

回复

6483

帖子

9

TA的资源

版主

4
 
dirty 发表于 2024-5-22 21:49 和平时用的RTOS系统用法一样,创建后使用

最近在用的AZURE_RTOS,就不太会注册,总是失败,要不就不运行,要不就只有它运行

此帖出自无线连接论坛

点评

看注册有没成功嘛,有没启动,参数等是否合理,异常的解决,资料这些多找找看看  详情 回复 发表于 2024-6-2 13:42
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 
 

回复

504

帖子

0

TA的资源

纯净的硅(初级)

5
 
秦天qintian0303 发表于 2024-5-23 09:38 最近在用的AZURE_RTOS,就不太会注册,总是失败,要不就不运行,要不就只有它运行

看注册有没成功嘛,有没启动,参数等是否合理,异常的解决,资料这些多找找看看

此帖出自无线连接论坛
个人签名

保持热爱

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
快速回复 返回顶部 返回列表