stm32cubemx hal学习记录:FreeRTOS消息队列
创始人
2024-02-06 08:39:48
0

一、基本介绍

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、生成代码

三、API

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;

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...