FREERTOS learning notes III - message queue
1. Experimental contents
Experiment 2: create two dynamic tasks. Task 1 controls the flashing of LED, and task 2 is used to detect keys. When the key KEY0 is pressed, task 1 is suspended; When key 1 is pressed, task 1 is cancelled and suspended.
In Experiment 3, a message queue and two task processes were added on the basis of Experiment 2; Task 2 key detection: when the key is pressed, a message will occur; Task 3 and task 4 are responsible for receiving messages.
2. Configuration of cubemx
1.1 add two tasks with the same priority
1.2 add message queue
The message size is 16 and the message format is unsigned 16 bits
1.3 add debugging serial port
2. Programming
2.1 printf function redirection
2.1.1 add header file
#include "stdio.h"
2.1.2 add redefine function
int fputc(int ch,FILE *f) { HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xFFFF);//hurat1 is the serial port number, which can be selected according to your own situation return ch; }
2.1.3 check use microlib
2.2 key task preparation
void StartKEY_Task(void const * argument) { /* USER CODE BEGIN StartKEY_Task */ /* Infinite loop */ uint16_t ProducerValue = 1; for(;;) { if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == 0) { osDelay(10);//Debounce if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == 0) { if(osMessagePut(myQueue01Handle,ProducerValue,0) != osOK)//0 indicates the waiting time after sending { osThreadSuspendAll(); printf("fail in send\r\n"); osThreadResumeAll(); } else { osThreadSuspendAll(); printf("Sent successfully\r\n"); ProducerValue++; osThreadResumeAll(); } } } while(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == 0)//Wait for the key to release to prevent continuous transmission { osDelay(10); } osDelay(1); } /* USER CODE END StartKEY_Task */ }
2.3 task 3 preparation
void StartTask03(void const * argument) { /* USER CODE BEGIN StartTask03 */ /* Infinite loop */ osEvent event; for(;;) { event = osMessageGet(myQueue01Handle,osWaitForever);//Waiting for news if(event.status == osEventMessage) { printf("Task 3 data:%d\r\n",event.value.v); } osDelay(1); } /* USER CODE END StartTask03 */ }
2.4 task 4 preparation
void StartTask04(void const * argument) { /* USER CODE BEGIN StartTask04 */ /* Infinite loop */ osEvent event; for(;;) { event = osMessageGet(myQueue01Handle,osWaitForever);//Waiting for news if(event.status == osEventMessage) { printf("Task 4 data:%d\r\n",event.value.v); } osDelay(1); osDelay(1); } /* USER CODE END StartTask04 */ }
3. Operation results 1
Task 3 and task 4 vie for time slice to receive messages
4. Improve the priority of task 3
5. Commissioning results 2
Because task 3 has a high priority, when task 3 receives a message using the osMessageGet() function, the message content will be deleted after it receives it, and then task 4 will not receive the message.
6. Change receiving function
Replace osMessageGet() of task 3 with osMessagePeek() receiving function
Also add in library function
event.value.v = 0;
Because this function is used to process 32-bit data, and the data used in this experiment is 16 bits. When processing data, this function will store the 16 bit data in the lower 16 bits of 32-bit data and supplement the high 16 bits with 1, which will lead to output result error (output - 65535). Therefore, adding this sentence can enable the function to set the high 16 position of 32 bits to 0
7. Commissioning results 3
Since the osMessagePeek() function will not delete the message after receiving the message, task 4 can receive the message.
8. Key functions
send message
osMessagePut(myQueue01Handle,ProducerValue,0)
Delete the received message of the message
event = osMessageGet(myQueue01Handle,osWaitForever);
Messages not received deleted
event = osMessagePeek(myQueue01Handle,osWaitForever);