1、消息队列就是一个像容器一样的东西,我们所有的任务都可以往内部写,然后队列会将我们的消息按顺序存下来,所有的任务也可以按顺序将其读出来。
2、队列需要明确数据的大小以及队列的长度,写队列和读队列都是采用赋值的方式将数据复制过去使用的。
3、数据的操作默认采用先进先出的方式,写数据时放到尾部,读数据时从头部读
1、配置RCC、USART1、时钟84MHz
2、配置SYS,将Timebase Source修改为除滴答定时器外的其他定时器。
3、初始化LED的两个引脚、两个按键引脚
4、开启FreeRTOS,v1与v2版本不同,一般选用v1即可
5、创建消息队列
Queue Name: 队列名称
Queue Size: 队列能够存储的最大单元数目,即队列深度
Queue Size: 队列中数据单元的长度,以字节为单位
Allocation: 分配方式:Dynamic 动态内存创建
Buffer Name: 缓冲区名称
Buffer Size: 缓冲区大小
Conrol Block Name: 控制块名称
6、创建两个线程,一个接收,一个发送
7、生成代码
1、队列ID:osMessageQId
osMessageQId TestQueueHandle;
2、使用动态内存的方式创建一个新的队列:osMessageCreate
osMessageQDef(TestQueue, 16, uint16_t);TestQueueHandle = osMessageCreate(osMessageQ(TestQueue), NULL);
3、队列删除:osMessageDelete
osMessageDelete(TestQueueHandle);
4、向队列尾部发送一个队列消息:osMessagePut
消息以拷贝的形式入队,而不是以引用的形式,可用在中断服务程序中。
osMessagePut(TestQueueHandle,send_data1,0);
三个参数分别为:消息队列的句柄,发送的消息内容,等待时间
void Send_thread_entry(void const * argument)
{/* USER CODE BEGIN Send_thread_entry *//* Infinite loop */osEvent xReturn;uint32_t send_data1;for(;;){if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8)==0){printf("send_data1\n");xReturn.status=osMessagePut(TestQueueHandle,send_data1,0);if(osOK!=xReturn.status){printf("send fail\n");}}osDelay(100);}/* USER CODE END Send_thread_entry */
}
5、从一个队列中接收消息并把消息从队列中删除:osMessageGet
接收的消息是以拷贝的形式进行的,所以我们必须提供一个足够大的空间的缓冲区,可以在中断服务中运行。
osMessageGet(TestQueueHandle,osWaitForever);
两个参数分别为:消息队列的句柄,等待时间(此时为一直等待)
void Receive_thread_entry(void const * argument)
{/* USER CODE BEGIN Receive_thread_entry *//* Infinite loop */osEvent event;for(;;){event=osMessageGet(TestQueueHandle,osWaitForever);if(osEventMessage==event.status){printf("receive data:%d\n",event.value.v);}else{printf("error:0x%d\n",event.status);}}/* USER CODE END Receive_thread_entry */
}
6、从队列中接收数据单元,但是并不删除接收到的单元:osMessagePeek
从队列中接收到数据后,不会修改队列中的数据,也不会改变数据在队列中的存储顺序
7、查询队列中当前有校的数据单元个数:osMessageWaiting
uint32_t a=osMessageWaiting(TestQueueHandle);
这个功能相当于在两个任务之间传递数据,一个发送,一个接收。
1、传输数字
①发送
void Send_thread_entry(void const * argument)
{osEvent xReturn;uint32_t send_data1;for(;;){printf("send_data1\n");xReturn.status=osMessagePut(TestQueueHandle,send_data1,0);if(osOK!=xReturn.status){printf("send fail\n");}osDelay(100);}
}
②接收
void Receive_thread_entry(void const * argument)
{osEvent event;for(;;){event=osMessageGet(TestQueueHandle,osWaitForever);if(osEventMessage==event.status){printf("receive data:%d\n",event.value.v);}else{printf("error:0x%d\n",event.status);}}
}
2、传输字符串或者结构体
①发送
typedef struct
{uint8_t name;uint8_t id;uint8_t age;
}T_data;void Send_thread_entry(void const * argument)
{for(;;){T_data m_data;m_data.age=20;m_data.id=2;m_data.name=1;osMessagePut(TestQueueHandle,(uint32_t)&m_data,0);osDelay(100);}
}
②接收
void Receive_thread_entry(void const * argument)
{osEvent event;for(;;){event=osMessageGet(TestQueueHandle,osWaitForever);if(event.status==osEventMessage){T_data *pData=(T_data *)event.value.p;printf("data=%d\n",pData->age);printf("id=%d\n",pData->id);printf("name=%d\n",pData->name);}}
}
3、以邮箱的形式传输数据
邮箱不能使用cubemx自动生成,需要手动添加
osMailQId mailQ01Handle;osMailQDef(mailQ01,15,T_data);
mailQ01Handle=osMailCreate(osMailQ(mailQ01),NULL);
①邮箱发送数据
T_data m_data;
m_data.age=20;
m_data.id=2;
m_data.name=1; osMailPut(mailQ01Handle,&m_data);
②邮箱接收数据
osEvent event=osMailGet(mailQ01Handle,osWaitForever);
if(event.status==osEventMail)
{T_data *m_Data=(T_data *)event.value.p;printf("data=%d\n",m_Data->age);printf("id=%d\n",m_Data->id);printf("name=%d\n",m_Data->name);
}
创建一个队列:
osMessageQId TestQueueHandle;
osMessageQDef(TestQueue, 16, uint16_t);
TestQueueHandle = osMessageCreate(osMessageQ(TestQueue), NULL);删除队列:
osMessageDelete(TestQueueHandle);
发送一个数字:
uint32_t send_data=100;
osMessagePut(myQueue01Handle,send_data,0);
接收一个数字:
osMessageGet(myQueue01Handle,osWaitForever);
发送一个字符串或者结构体:
typedef struct
{
uint8_t name;
uint8_t age;
uint8_t id;
}T_Data;T_Data m_data;
m_data.age=18;
m_data.name=12;
m_data.id=123;
osMessagePut(myQueue01Handle,(uint32_t)&m_data,0);
接收一个字符或者结构体:
uint8_t name;
uint8_t id;
uint8_t age;osEvent event=osMessageGet(myQueue01Handle,osWaitForever);
T_Data *p_data=(T_Data *)event.value.p;
name=p_data->name;
id=p_data->id;
age=p_data->age;
创建邮箱:
osMailQId mailQ01Handle;
收发的类型设置为结构体T_data
osMailQDef(mailQ01,15,T_data);
mailQ01Handle=osMailCreate(osMailQ(mailQ01),NULL);邮箱发送数据:
T_Data m_data;
m_data.age=18;
m_data.name=12;
m_data.id=123;
osMailPut(mailQ01Handle,&m_data);邮箱接收数据:
osEvent event=osMailGet(mailQ01Handle,osWaitForever);
T_Data *p_data=(T_Data *)event.value.p;
name=p_data->name;
id=p_data->id;
age=p_data->age;