HAL库使用FreeRTOS队列集

由于本人在使用stm32cubemx的freertos时,没有发现队列集配置的选项,因此记录一下如何手动在cubemx生成的freertos中创建和使用队列集。

首先队列集的作用是对多个队列和信号量进行“监听”,不管其中哪一个到来都会使任务退出阻塞。

硬件:正点原子miniV3.0

环境:cubemx、keil5

参考教程:【【正点原子】手把手教你学FreeRTOS实时系统】https://www.bilibili.com/video/BV19g411p7UT?p=47&vd_source=d1e91e9e17a031e2d6e11ed04c3ab205

队列集的使用方法:

  1. 在freertos.h中配置宏configUSE_QUEUE_SETS为1;
  2. 创建队列集,队列集创建函数的参数为2表示最多可以放入两个队列(信号量本质也是队列),至于队列的长度不做限制;
  3. 创建队列或信号量;
  4. 往队列集中添加队列或信号量,注意将队列添加到队列集中时队列中不能有有效消息。如果是信号量那么信号量应该为0;
  5. 往队列中发送信息或释放信号量;
  6. 获取队列集的消息;

这里拿添加二值信号量和队列为例子,注意cubemx生成的二值信号量默认值为1,因此需要在代码中将其初始值修改为0,否则无法对其进行监听。主要代码如下:

freertos.h


#ifndef configUSE_QUEUE_SETS
    #define configUSE_QUEUE_SETS 1
#endif
freertos.c:

/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "usart.h"
#include "Key.h"
#include "Delay.h"
#include "queue.h"
#include "semphr.h"
/* USER CODE END Includes */


/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */

QueueSetHandle_t queueset01_handle;   //创建队列集句柄



/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */


  /* Create the semaphores(s) */
  /* creation of myBinarySem01 */
  myBinarySem01Handle = osSemaphoreNew(1, 0, &myBinarySem01_attributes);



  /* Create the queue(s) */
  /* creation of myQueue01 */
  myQueue01Handle = osMessageQueueNew (2, sizeof(uint8_t), &myQueue01_attributes);


  /* Create the thread(s) */
  /* creation of myTask01 */
  myTask01Handle = osThreadNew(StartTask01, NULL, &myTask01_attributes);

  /* creation of myTask03 */
  myTask03Handle = osThreadNew(StartTask03, NULL, &myTask03_attributes);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
//队列集创建函数的参数为2表示最多可以放入两个队列(信号量本质也是队列),至于队列的长度不做限制
	queueset01_handle = xQueueCreateSet( 2 );  
	if(queueset01_handle != NULL)
		myprintf("队列集创建成功\r\n");
	
	xQueueAddToSet(myBinarySem01Handle,queueset01_handle);  //添加信号量到队列集
	xQueueAddToSet(myQueue01Handle,queueset01_handle);      //添加队列到队列集
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_EVENTS */
  /* add events, ... */
  /* USER CODE END RTOS_EVENTS */

}

/* USER CODE BEGIN Header_StartTask01 */
/**
  * @brief  Function implementing the myTask01 thread.
  * @param  argument: Not used
  * @retval None
  */

uint8_t key = 0;
/* USER CODE END Header_StartTask01 */
void StartTask01(void *argument)
{
  /* USER CODE BEGIN StartTask01 */
  /* Infinite loop */
	QueueSetMemberHandle_t member_handle;
	uint8_t value;
  for(;;)
  {
		member_handle = xQueueSelectFromSet(queueset01_handle,portMAX_DELAY);
		if(member_handle == myQueue01Handle)
		{
			osMessageQueueGet(member_handle ,&value ,0 , portMAX_DELAY);
			myprintf("获取队列数据数据:%d\r\n",value);
		}
		if(member_handle == myBinarySem01Handle)
		{
			osSemaphoreAcquire(member_handle,portMAX_DELAY);
			myprintf("获取信号量成功\r\n");
		}
  }
  /* USER CODE END StartTask01 */
}


/* USER CODE BEGIN Header_StartTask03 */
/**
* @brief Function implementing the myTask03 thread.
* @param argument: Not used
* @retval None
*/

uint8_t state;
/* USER CODE END Header_StartTask03 */
void StartTask03(void *argument)
{
  /* USER CODE BEGIN StartTask03 */
  /* Infinite loop */
	uint8_t key = 0;

  for(;;)
  {
		key = KEY_Scan(0);    //保存返回值,方便后面判断
		if(key == KEY0_PRES)
		{
			state = osMessageQueuePut(myQueue01Handle ,&key ,0 , portMAX_DELAY);
			if(state == osOK)  myprintf("往队列写入数据成功\r\n");
		}
		if(key == KEY1_PRES)
		{
				state = osSemaphoreRelease(myBinarySem01Handle);
			  if(state == osOK)  myprintf("二值信号量释放成功\r\n");
			  else  myprintf("二值信号量释放失败\r\n");
		}
    osDelay(10);
  }
  /* USER CODE END StartTask03 */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */

/* USER CODE END Application */

任务三功能就是按下key0,往队列写数据,按下key1释放二值信号量

任务一功能就是对队列集中的队列和信号量进行监听,有有效值就打印

结果如下:

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值