esp32里面跑的是freertos,如果需要传递数据需要使用内部的缓存管理.

任务间同步

RTOS中的同步,是指不同任务之间或者任务与外部事件之间的协同工作方式,确保多个并发执行的任务按照预期的顺序或时机执行。它设计到线程或任务间的通信和协调机制,目的是为了避免数据竞争、解决竞态条件,并确保系统的正确行为。

互斥是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排他性。

![[Pasted image 20250518093926.png]]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
QueueHandle_t xQueueCreate(//创建一个队列,成功返回队列句柄
UBaseType_t uxQueueLength,//队列容量
UBaseType_t uxltemSize //每个队列项所占内存的大小(单位是字节)
);

BaseType_t xQueueSend(//向队列头部发送一个消息
QueueHandle_t xQueue,//队列句柄
const void * pvItemToQueue,//要发送的消息指针
TickType_t xTicksToWait//等待时间
);

BaseType_t xQueueSendToBack(//向队列尾部发送一个消息
QueueHandle_t xQueue,//队列句柄
const void * pvItemToQueue,//要发送的消息指针
TickType_t xTicksToWait//等待时间
);


BaseType_t xQueueReceive(//从队列接收一条信息
QueueHandle_t xQueue,//队列句柄
void * const pvBuffer,//指向接收消息缓冲区的指针
TickType_t xTicksToWait//等待时间
);

BaseType_t xQueueSendFromISR(//xQueueSend的中断版本
QueueHandle_t xQueue,//队列句柄
const void * pvItemToQueue,//要发送的消息指针
BaseType_t *pxHigherPriorityTaskWoken//如果发送到队列导致任务解除阻塞,且解除阻塞的任务的优先级高于当前运行的任务,则xQueueSendFromISR会将 *pxHigherPriorityTaskWoken设置为pdTRUE,如果xQueueSendFromISR()将此值设置为pdTRUE,则应在中断退出前要执行请求上下文切换函数
);

实例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <stdio.h>
#include "esp_log.h" // ESP-IDF 日志模块
#include "freertos/FreeRTOS.h" // FreeRTOS 主头文件
#include "freertos/task.h" // 任务管理相关
#include "freertos/queue.h" // 队列管理相关
#include "string.h" // 字符串和内存操作

// 创建一个队列句柄,用于任务之间的通信
QueueHandle_t queue_handle = NULL;

// 定义一个结构体,用于传输的数据类型
typedef struct
{
int value; // 整型数据字段
} queue_data_t;

// 任务A:从队列中接收数据并打印出来
void TaskA(void * param)
{
queue_data_t data;
while (1)
{
// 尝试接收队列中的数据,超时时间为100个Tick
if(pdTRUE == xQueueReceive(queue_handle, &data, 100))
{
ESP_LOGI("queue", "receive queue value: %d", data.value);
}
// 若没有数据可读,则会超时后继续下一轮循环
}
}

// 任务B:每隔1秒向队列中发送数据
void TaskB(void * param)
{
queue_data_t data;
memset(&data, 0, sizeof(queue_data_t)); // 将结构体初始化为0

while (1)
{
// 向队列中发送数据,超时时间为100个Tick
xQueueSend(queue_handle, &data, 100);

// 任务延时1秒(1000ms)
vTaskDelay(pdMS_TO_TICKS(1000));

// 每次发送后将value加1
data.value++;
}
}

// 主函数:系统入口点
void app_main(void)
{
// 创建一个长度为10的队列,每个元素大小为queue_data_t结构体的大小
queue_handle = xQueueCreate(10, sizeof(queue_data_t));

// 创建任务A,运行在核心1上,优先级为3,栈大小2048字节
xTaskCreatePinnedToCore(TaskA, "taskA", 2048, NULL, 3, NULL, 1);

// 创建任务B,同样运行在核心1上
xTaskCreatePinnedToCore(TaskB, "taskB", 2048, NULL, 3, NULL, 1);
}

![[Pasted image 20250518104230.png]]