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;