当前位置:首页 >> 智能终端演进 >> 【STM32】FreeRTOS消息队列和信号量学习,酷睿i3530

【STM32】FreeRTOS消息队列和信号量学习,酷睿i3530

cpugpu芯片开发光刻机 智能终端演进 1
文件名:【STM32】FreeRTOS消息队列和信号量学习,酷睿i3530 【STM32】FreeRTOS消息队列和信号量学习

一、消息队列(queue)

队列是一种用于实现任务与任务之间,任务与中断之间消息交流的机制。

注意:1.数据的操作是FIFO模式。

2.队列需要明确数据的大小和队列的长度。

3.写和读都会出现堵塞。

实验:创建一个消息队列,两个发送任务,一个接收任务。

其中任务一任务三的等待时间为0,任务二的等待时间为portMAX_DELAY(死等)。

实现:在前一个项目的基础上进行更改【STM32】利用CubeMX对FreeRTOS用按键控制任务

void MX_FREERTOS_Init(void) {/* USER CODE BEGIN Init *//* USER CODE END Init *//* USER CODE BEGIN RTOS_MUTEX *//* add mutexes, ... *//* USER CODE END RTOS_MUTEX *//* Create the semaphores(s) *//* USER CODE BEGIN RTOS_SEMAPHORES *//* add semaphores, ... *//* USER CODE END RTOS_SEMAPHORES *//* USER CODE BEGIN RTOS_TIMERS *//* start timers, add new ones, ... *//* USER CODE END RTOS_TIMERS *//* Create the queue(s) *//* definition and creation of myQueue01 */osMessageQDef(myQueue01, 2, uint32_t);myQueue01Handle = osMessageCreate(osMessageQ(myQueue01), NULL);/* USER CODE BEGIN RTOS_QUEUES *//* add queues, ... *//* USER CODE END RTOS_QUEUES *//* Create the thread(s) *//* definition and creation of Task1 */osThreadDef(Task1, StartDefaultTask, osPriorityNormal, 0, 128);Task1Handle = osThreadCreate(osThread(Task1), NULL);/* definition and creation of Task2 */osThreadDef(Task2, StartTask02, osPriorityIdle, 0, 128);Task2Handle = osThreadCreate(osThread(Task2), NULL);/* definition and creation of Task3 */osThreadDef(Task3, StartTask03, osPriorityIdle, 0, 128);Task3Handle = osThreadCreate(osThread(Task3), NULL);/* USER CODE BEGIN RTOS_THREADS *//* add threads, ... *//* USER CODE END RTOS_THREADS */}/* USER CODE BEGIN Header_StartDefaultTask *//*** @brief Function implementing the Task1 thread.* @param argument: Not used* @retval None*//* USER CODE END Header_StartDefaultTask */void StartDefaultTask(void const * argument){/* USER CODE BEGIN StartDefaultTask *//* Infinite loop */BaseType_t xStatus;uint32_t Buf=10086;for(;;){if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==0){osDelay(20);if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==0){xStatus=xQueueSendToBack(myQueue01Handle,&Buf,0);if(xStatus!=pdTRUE){printf("NO1\r\n");osDelay(500);}else{printf("YES1%u\r\n",Buf);osDelay(500);}}}}/* USER CODE END StartDefaultTask */}/* USER CODE BEGIN Header_StartTask02 *//*** @brief Function implementing the Task2 thread.* @param argument: Not used* @retval None*//* USER CODE END Header_StartTask02 */void StartTask02(void const * argument){/* USER CODE BEGIN StartTask02 *//* Infinite loop */BaseType_t xStatus;uint32_t Buf=66666;for(;;){if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0){osDelay(20);if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0){xStatus=xQueueSendToBack(myQueue01Handle,&Buf,portMAX_DELAY);if(xStatus!=pdTRUE){printf("NO2\r\n");osDelay(500);}else{printf("YES2%u\r\n",Buf);osDelay(500);}}}}/* USER CODE END StartTask02 */}/* USER CODE BEGIN Header_StartTask03 *//*** @brief Function implementing the Task3 thread.* @param argument: Not used* @retval None*//* USER CODE END Header_StartTask03 */void StartTask03(void const * argument){/* USER CODE BEGIN StartTask03 *//* Infinite loop *///BaseType_t xStatus;uint32_t Buf=0;for(;;){if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2)==0){osDelay(20);if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2)==0){printf("当前%u\r\n",Buf);//xStatus=xQueueReceive(myQueue01Handle,&Buf,portMAX_DELAY);if(xQueueReceive(myQueue01Handle,&Buf,portMAX_DELAY)!=pdTRUE){printf("NO3\r\n");}else{printf("YES3%u\r\n",Buf);}}}}/* USER CODE END StartTask03 */}

现象:队列满了以后,任务一无法发送,任务二会死等,队列空闲以后完成发送。

二、信号量

消息队列用于传输多个数据,占用时间也相对较长,但有时只需要传输状态,因此引入信号量。信号量也是队列的一种。信号量有两种,如果它的量只有0(被拿走的状态)和1(被填入的状态)两种状态,就称为二进制的信号量;当量的状态大于两种,就称为计数型信号量。

1.二值信号量

实验:任务一:按键采集数据;任务二:拿走以后串口发送信息

实现:

void MX_FREERTOS_Init(void) {/* USER CODE BEGIN Init *//* USER CODE END Init *//* USER CODE BEGIN RTOS_MUTEX *//* add mutexes, ... *//* USER CODE END RTOS_MUTEX *//* Create the semaphores(s) *//* definition and creation of myBinarySem01 */osSemaphoreDef(myBinarySem01);myBinarySem01Handle = osSemaphoreCreate(osSemaphore(myBinarySem01), 1);/* USER CODE BEGIN RTOS_SEMAPHORES *//* add semaphores, ... *//* USER CODE END RTOS_SEMAPHORES *//* USER CODE BEGIN RTOS_TIMERS *//* start timers, add new ones, ... *//* USER CODE END RTOS_TIMERS *//* Create the queue(s) *//* definition and creation of myQueue01 */osMessageQDef(myQueue01, 2, uint32_t);myQueue01Handle = osMessageCreate(osMessageQ(myQueue01), NULL);/* USER CODE BEGIN RTOS_QUEUES *//* add queues, ... *//* USER CODE END RTOS_QUEUES *//* Create the thread(s) *//* definition and creation of Task1 */osThreadDef(Task1, StartDefaultTask, osPriorityNormal, 0, 128);Task1Handle = osThreadCreate(osThread(Task1), NULL);/* definition and creation of Task2 */osThreadDef(Task2, StartTask02, osPriorityNormal, 0, 128);Task2Handle = osThreadCreate(osThread(Task2), NULL);/* definition and creation of Task3 */osThreadDef(Task3, StartTask03, osPriorityNormal, 0, 128);Task3Handle = osThreadCreate(osThread(Task3), NULL);/* USER CODE BEGIN RTOS_THREADS *//* add threads, ... *//* USER CODE END RTOS_THREADS */}/* USER CODE BEGIN Header_StartDefaultTask *//*** @brief Function implementing the Task1 thread.* @param argument: Not used* @retval None*//* USER CODE END Header_StartDefaultTask */void StartDefaultTask(void const * argument){/* USER CODE BEGIN StartDefaultTask *//* Infinite loop */BaseType_t xStatus;uint32_t Buf=10086;for(;;){// {if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==0){osDelay(20);if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==0){//xStatus=xQueueSendToBack(myQueue01Handle,&Buf,0);if(xSemaphoreGive(myBinarySem01Handle)==pdTRUE){printf("NO1\r\n");}else{printf("YES1%u\r\n",Buf);}}}}/* USER CODE END StartDefaultTask */}/* USER CODE BEGIN Header_StartTask03 *//*** @brief Function implementing the Task3 thread.* @param argument: Not used* @retval None*//* USER CODE END Header_StartTask03 */void StartTask03(void const * argument){/* USER CODE BEGIN StartTask03 *//* Infinite loop */uint32_t Buf=0;for(;;){if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2)==0){osDelay(20);if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2)==0){if(xSemaphoreTake(myBinarySem01Handle,0)==pdTRUE){printf("YES3\r\n");}else{printf("NO3%u\r\n",Buf);}}}}/* USER CODE END StartTask03 */}

 现象:当按键释放了信号量,串口才能成功发送信息。

2.记数型信号量

实验:任务一 :按键一记录人进来;按键二记录人出去;(最多有10个人)

任务二:串口每隔3S打印人数。

实现:

void MX_FREERTOS_Init(void) {/* USER CODE BEGIN Init *//* USER CODE END Init *//* USER CODE BEGIN RTOS_MUTEX *//* add mutexes, ... *//* USER CODE END RTOS_MUTEX *//* Create the semaphores(s) *//* definition and creation of myBinarySem01 */osSemaphoreDef(myBinarySem01);myBinarySem01Handle = osSemaphoreCreate(osSemaphore(myBinarySem01), 1);/* definition and creation of myCountingSem01 */osSemaphoreDef(myCountingSem01);myCountingSem01Handle = osSemaphoreCreate(osSemaphore(myCountingSem01), 10);/* USER CODE BEGIN RTOS_SEMAPHORES *//* add semaphores, ... *//* USER CODE END RTOS_SEMAPHORES *//* USER CODE BEGIN RTOS_TIMERS *//* start timers, add new ones, ... *//* USER CODE END RTOS_TIMERS *//* Create the queue(s) *//* definition and creation of myQueue01 */osMessageQDef(myQueue01, 2, uint32_t);myQueue01Handle = osMessageCreate(osMessageQ(myQueue01), NULL);/* USER CODE BEGIN RTOS_QUEUES *//* add queues, ... *//* USER CODE END RTOS_QUEUES *//* Create the thread(s) *//* definition and creation of Task1 */osThreadDef(Task1, StartDefaultTask, osPriorityNormal, 0, 128);Task1Handle = osThreadCreate(osThread(Task1), NULL);/* definition and creation of Task2 */osThreadDef(Task2, StartTask02, osPriorityNormal, 0, 128);Task2Handle = osThreadCreate(osThread(Task2), NULL);/* definition and creation of Task3 */osThreadDef(Task3, StartTask03, osPriorityNormal, 0, 128);Task3Handle = osThreadCreate(osThread(Task3), NULL);/* USER CODE BEGIN RTOS_THREADS *//* add threads, ... *//* USER CODE END RTOS_THREADS */}/* USER CODE BEGIN Header_StartDefaultTask *//*** @brief Function implementing the Task1 thread.* @param argument: Not used* @retval None*//* USER CODE END Header_StartDefaultTask */void StartDefaultTask(void const * argument){/* USER CODE BEGIN StartDefaultTask *//* Infinite loop */for(;;){if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==0){osDelay(20);if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==0){if(xSemaphoreGive(myCountingSem01Handle)!=pdTRUE){printf("NO1\r\n");}else{printf("YES1\r\n");}}}if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0){osDelay(20);if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0){if(xSemaphoreTake(myCountingSem01Handle,0)!=pdTRUE){printf("NO2\r\n");}else{printf("YES2\r\n");}}}}/* USER CODE END StartDefaultTask */}/* USER CODE BEGIN Header_StartTask02 *//*** @brief Function implementing the Task2 thread.* @param argument: Not used* @retval None*//* USER CODE END Header_StartTask02 */void StartTask02(void const * argument){/* USER CODE BEGIN StartTask02 *//* Infinite loop */for(;;){}/* USER CODE END StartTask02 */}/* USER CODE BEGIN Header_StartTask03 *//*** @brief Function implementing the Task3 thread.* @param argument: Not used* @retval None*//* USER CODE END Header_StartTask03 */void StartTask03(void const * argument){/* USER CODE BEGIN StartTask03 *//* Infinite loop */for(;;){printf("possess %d people\r\n",(uint16_t)uxSemaphoreGetCount(myCountingSem01Handle));osDelay(3000);}/* USER CODE END StartTask03 */}

 因为用了函数

myCountingSem01Handle = osSemaphoreCreate(osSemaphore(myCountingSem01), 10);

默认当前计数值为满值。如果设置为0,使用下面的函数:

myCountingSem01Handle=xSemaphoreCreateCounting(10,0);

现象:通过按键一和二实现记录人数,并串口打印了当前人数。

协助本站SEO优化一下,谢谢!
关键词不能为空
同类推荐
«    2025年12月    »
1234567
891011121314
15161718192021
22232425262728
293031
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
搜索
最新留言
文章归档
网站收藏
友情链接