【Beetle ESP32 C6迷你开发板】--4.FreeRTOS任务与消息队列
<div class='showpostmsg'><p> 本篇讲述串口接收数据,通过消息队列发送和任务接收消息队列。</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 <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();</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 > 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 = 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 *)&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, &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> 编译烧录后可看到初始化情况,在串口发送数据,可看到串口接收并将数据消息队列发送出去,任务接收到消息队列并打印出来,实现了消息队列的成功收发。</p>
<div style="text-align: center;"></div>
<div style="text-align: center;">图1:任务与消息队列发送与接收</div>
<p> 由此,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> <p>FreeRTOS必须要先注册才能使用吗? </p>
秦天qintian0303 发表于 2024-5-18 11:10
FreeRTOS必须要先注册才能使用吗?
<p>和平时用的RTOS系统用法一样,创建后使用</p>
dirty 发表于 2024-5-22 21:49
和平时用的RTOS系统用法一样,创建后使用
<p>最近在用的AZURE_RTOS,就不太会注册,总是失败,要不就不运行,要不就只有它运行</p>
秦天qintian0303 发表于 2024-5-23 09:38
最近在用的AZURE_RTOS,就不太会注册,总是失败,要不就不运行,要不就只有它运行
<p>看注册有没成功嘛,有没启动,参数等是否合理,异常的解决,资料这些多找找看看</p>
页:
[1]