FreeRTOS-- message queue

In any of the RTOS, it has an important communication mechanism ---- message queue.

Queue is the main form of communication between tasks. They can be used between tasks, and the interrupt sending messages between tasks. In most cases, they are used as thread-safe FIFO (First In First Out) buffer, the new data is sent back to the queue, but data can be sent to the front.

 

The concept and its role Message Queue (the basis of the following content reproduced from Fu Lai Electronics)

Message Queuing Service is provided by the RTOS kernel task or interrupt service routine may be a message (note, the FreeRTOS message queue actual data transfer, the data is not address, RTX, uCOS-II uCOS-III and is the address of the transfer ) input to the queue. Likewise, one or more tasks can be obtained from the queue by the RTOS kernel service. Typically, the first to enter the message queue to pass the first task, that is to say, the first task is to get the message into the message queue, namely the principle of first in first out (FIFO), FreeRTOS message queue support two FIFO and LIFO species data access mode. There may not understand the use of message queues beginners will ask much trouble, put forward a global array instead of the more simple, it is not. When bare metal programming, using global arrays and is more convenient, but after adding RTOS is a different story. Compared message queue using four global arrays have the following main problems: 

♦ Use message queue allows RTOS kernel to efficiently manage tasks, and global arrays can not be done, overtime and other mechanisms tasks require the user to achieve.

♦ Use a global array will prevent access conflicts multitasking, while the use of message queues to handle this problem, users do not need to worry about.

♦ Use message queue can effectively solve the problem of interrupt service routines and message passing between tasks.

♦ FIFO mechanism more conducive to processing data.

 

Here I will create two threads, monitor Task and control Task. Message sent by the monitor Task, control Task accept message, printing different information according to the message type.

1. Based on STM32Cube configuration FreeRTOS, I'm here with the STM32F103RCT6, first Enable FreeRTOS, configure RCC external high-speed crystal 8M HZ

 

 

 Configuring the serial print USART1, HAL reference clock source TIM1, RTOS will systick clock source.

 

 

 3. Configure the clock tree

 

 

 4. Configuration FreeRTOS

 

 

 

 

 

 The generated code configuration

 

 

 

 

 

 The main function of generating primary, System, GPIO, USART, FreeRTOS initialization, once started thread scheduling, Task started, while in the main not enter.

 1 int main(void)
 2 {
 3   /* USER CODE BEGIN 1 */
 4 
 5   /* USER CODE END 1 */
 6 
 7   /* MCU Configuration----------------------------------------------------------*/
 8 
 9   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
10   HAL_Init();
11 
12   /* USER CODE BEGIN Init */
13 
14   /* USER CODE END Init */
15 
16   /* Configure the system clock */
17   SystemClock_Config();
18 
19   /* USER CODE BEGIN SysInit */
20 
21   /* USER CODE END SysInit */
22 
23   /* Initialize all configured peripherals */
24   MX_GPIO_Init();
25   MX_USART1_UART_Init();
26 27
28   /* Initialize interrupts */
29   MX_NVIC_Init();
30   /* USER CODE BEGIN 2 */
31   printf("Test Message Queue!\n");
32   /* USER CODE END 2 */
33 
34   /* Call init function for freertos objects (in freertos.c) */
35   MX_FREERTOS_Init();
36 
37   /* Start scheduler */
38   osKernelStart();
39   
40   /* We should never get here as control is now taken by the scheduler */
41 
42   /* Infinite loop */
43   /* USER CODE BEGIN WHILE */
44   while (1)
45   {
46 
47   /* USER CODE END WHILE */
48 
49   /* USER CODE BEGIN 3 */
50 
51   }
52   /* USER CODE END 3 */
53 
54 }

Definition of message structure:

 1 /* USER CODE BEGIN Variables */
 2 typedef enum _Msg_Type_
 3 {
 4     MSG_TYPE_LED,
 5     MSG_TYPE_LED_TOGGLE,
 6     MSG_TYPE_BUZZER,
 7     MSG_TYPE_MAX
 8 }MsgType;
 9 
10 typedef struct _Msg
11 {
12     MsgType msgType;
13     bool    bswitch;
14 }Msg;
15 
16 17 /* USER CODE END Variables */

Debug_Printf to define print serial information

void  Debug_Printf(char *format, ...)
{
    char  buf_str[128];
    va_list   v_args;


    va_start(v_args, format);
   (void)vsnprintf((char       *)&buf_str[0],
                   (size_t      ) sizeof(buf_str),
                   (char const *) format,
                                  v_args);
    va_end(v_args);

    /* 互斥信号量 */
    osMutexWait(Mutex_printfHandle,osWaitForever);
    printf("[%ldms]%s",xTaskGetTickCount(),buf_str);
    osMutexRelease(Mutex_printfHandle);
}

FreeRTOS initialization

/* Init FreeRTOS */

void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */
       
  /* USER CODE END Init */

  /* Create the mutex(es) */
  /* definition and creation of Mutex_printf */
  osMutexDef(Mutex_printf);
  Mutex_printfHandle = osMutexCreate(osMutex(Mutex_printf));

  /* 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 thread(s) */
  /* definition and creation of vTask1 */
  osThreadDef(vTask1, monitor_task, osPriorityNormal, 0, 256);
  vTask1Handle = osThreadCreate(osThread(vTask1), NULL);

  /* definition and creation of vTaks2 * / 
  OsThreadDef (vTaks2, control_task, osPriorityNormal, 0 , 256 ); 
  vTaks2Handle = osThreadCreate (osThread (vTaks2), NULL); 

  / * the USER CODE RTOS_THREADS the BEGIN * / 
  / * the Add Threads, ... * / 
  / * the USER CODE the END RTOS_THREADS * / 

  / * the Create the queue (S) * / 
  / * Definition and Creation of MsgQueue * / 
  osMessageQDef (MsgQueue, 16 , Msg); // define the message queue depth and magnitude of the load 
  msgQueueHandle = osMessageCreate (osMessageQ (MsgQueue), NULL); 

  / * the USER CODE RTOS_QUEUES the BEGIN * /
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */
}

/* monitor_task function */
void monitor_task(void const * argument)
{

  /* USER CODE BEGIN monitor_task */
  int cnt = 0;
  Msg msg;

  Debug_Printf("Enter monitor task!\n");


  /* Infinite loop */
  for(;;)
  {
    cnt++;
    if(cnt == 1 )
    {
        msg.msgType = MSG_TYPE_LED;
        msg.bswitch = true;
        xQueueSend(msgQueueHandle,&msg,10);
    }
    else if(cnt == 5)
    {
        msg.msgType = MSG_TYPE_LED;
        msg.bswitch = false;
        xQueueSend(msgQueueHandle,&msg,10);
    }
    else if(cnt == 10)
    {
        msg.msgType = MSG_TYPE_LED_TOGGLE;
        msg.bswitch = true;
        xQueueSend(msgQueueHandle,&msg,10);
    }
    osDelay(1000);

  }
  /* USER CODE END monitor_task */
}

/* control_task function */
void control_task(void const * argument)
{
  /* USER CODE BEGIN control_task */
  Msg tempMsg ;

  Debug_Printf("Enter control task!\n");
  /* Infinite loop */
  for(;;)
  {
    xQueueReceive(msgQueueHandle,(void*)&tempMsg,osWaitForever);

    switch(tempMsg.msgType)
    {
        case MSG_TYPE_LED:
            if(tempMsg.bswitch)
            {
                Debug_Printf("LED is Open!\n");
            }
            else
            {
                Debug_Printf("LED is Closed!\n");
            }
            break;

        case MSG_TYPE_LED_TOGGLE:
            if(tempMsg.bswitch)
            {
                Debug_Printf("LED is Toggling!\n");
            }
            else
            {
                Debug_Printf("LED is off!\n");
            }
            break;

        default:
            break;
    }
    osDelay(10);
  }
  /* USER CODE END control_task */
}

Test Results: As can be seen by a stamp system, first control Task sends a message type MSG_TYPE_LED,

Message load Open, transmission over 4 seconds MSG_TYPE_LED, load the Close message; transmitting another 5 seconds MSG_TYPE_LED_TOGGLE

 

Guess you like

Origin www.cnblogs.com/mickey-double/p/11577842.html