dirty 发表于 2024-5-18 09:34

【Beetle ESP32 C6迷你开发板】--4.FreeRTOS任务与消息队列

<div class='showpostmsg'><p>&nbsp; &nbsp; &nbsp; 本篇讲述串口接收数据,通过消息队列发送和任务接收消息队列。</p>

<p><strong><span style="color:#0000ff;">一.代码准备</span></strong></p>

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

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

<p>2.创建消息队列</p>

<pre>
<code>// Create the queue which will have &lt;QueueElementSize&gt; number of elements, each of size `message_t` and pass the address to &lt;QueueHandle&gt;.
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();</code></pre>

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

<pre>
<code>
//任务检查串口接收,有数据就消息队列发送出去
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 &gt; 0) {
      // Check if the queue exists AND if there is any free space in the queue
      if (QueueHandle != NULL &amp;&amp; uxQueueSpacesAvailable(QueueHandle) &gt; 0) {
      int max_length = message.line_length &lt; MAX_LINE_LENGTH ? message.line_length : MAX_LINE_LENGTH - 1;
      for (int i = 0; i &lt; max_length; ++i) {
          message.line = Serial.read();
      }
      message.line_length = max_length;
      message.line = 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 *)&amp;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();
}</code></pre>

<p>4.创建消息队列接收任务</p>

<pre>
<code>//消息队接收任务
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, &amp;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();}</code></pre>

<p><strong><span style="color:#0000ff;">二.编译烧录测验</span></strong></p>

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

<div style="text-align: center;"></div>

<div style="text-align: center;">图1:任务与消息队列发送与接收</div>

<p>&nbsp; &nbsp; &nbsp; 由此,Beetle ESP32 C6可用FreeRTOS实现系统功能。</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

秦天qintian0303 发表于 2024-5-18 11:10

<p>FreeRTOS必须要先注册才能使用吗?&nbsp;&nbsp;</p>

dirty 发表于 2024-5-22 21:49

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

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

秦天qintian0303 发表于 2024-5-23 09:38

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

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

dirty 发表于 2024-6-2 13:42

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

<p>看注册有没成功嘛,有没启动,参数等是否合理,异常的解决,资料这些多找找看看</p>
页: [1]
查看完整版本: 【Beetle ESP32 C6迷你开发板】--4.FreeRTOS任务与消息队列