前言
- 我的理解是 消息队列主要是用于任务之间存在主从关系的时候,比如说显示屏显示数据,显示屏的作用只是提供显示,数据来源应该是其他任务线程,所以就存在多个线程通信问题。
FreeRTOS中消息队列
- 这里我们以数组为例(字符数组)
源码分析
消息队列的创建(主要步骤)
xDisplayQue = xQueueCreate(10, sizeof(uint32_t));
消息的发送
消息的接收
demo(核心部分)
创建
QueueHandle_t xDisplayQue;
xDisplayQue = xQueueCreate(10, sizeof(uint32_t));
configASSERT(xDisplayQue);
发送
static char msg[20] = {0};
uint32_t addr = (uint32_t) (msg);
while (1) {
if (xDisplayQue != NULL) {
sprintf(msg, "hello word:%lu", xTaskGetTickCount());
printf("发送消息:%s,%#lx\r\n", msg, addr);
xQueueSend(xDisplayQue, &addr, (TickType_t) 0);
// xQueueSend(xDisplayQue, &msg, (TickType_t) 0);/*这种写法是错误的,后面拷贝数据的时候,是拷贝的是msg保存内容的前4个字节*/
vTaskDelay(10000);
}
}
接收
uint32_t msg_addr;
for (;;) {
if (xDisplayQue != 0) {
// 在创建的队列上接收消息。 阻止 10 个刻度,如果消息无法立即获得。
if (xQueueReceive(xDisplayQue, (void *) &msg_addr, (TickType_t) 10) == pdTRUE) {
printf("接收到消息:%s\r\n", ((char *) msg_addr));
//LCD_ShowString(30, 30, 130, 130, 12, msg);
}
vTaskDelay(20);
}
}
测试结果
证明传递数组是值拷贝
- 注意在消息队列中发送数据的时候,数据传送的是什么?如果涉及到数组,都是说的值拷贝,而不是地址拷贝
- 这涉及到数组的概念
- 数组名表示首地址,&数组名[0]表示数组第一个元素的地址也等于数组的首地址
这样在用消息队列拷贝的过程中传递数组或对数组去地址都是一样的地址,在底层拷贝的时候,就是通过拷贝该地址的数据前几个字节,而不是拷贝地址。