Darren_pty

导航

10-FreeRTOS 队列

实验内容:

①创建三个任务,任务一向队列里发送数据100,任务二向队列发送数据200,任务三从队列里面读取数据;

②任务一和任务二优先级相同,任务三优先级大于任务一二。

 

 

代码:

 //----------------------------------------任务优先级
 #define SENDER_TASK1            1 
 #define SENDER_TASK2            1 
 #define RECEIVER_TASK           2 //优先级高
 
 
 //----------------------------------------任务堆栈大小
 #define SENDER1_STK_SIZE    128 
 #define SENDER2_STK_SIZE    128 
 #define RECEIVER_STK_SIZE   256 

 
 //----------------------------------------任务 & 队列句柄
 TaskHandle_t Task1_Handler; 
 TaskHandle_t Task2_Handler; 
 TaskHandle_t StartTask_Handler;

 xQueueHandle xQueue;//队列句柄
 
 
 //----------------------------------------任务函数
 void vSenderTask1(void *pvParameters);    //向队列里面发送数据100
 void vSenderTask2(void *pvParameters);    //向队列里面发送数据200
 void vReceiverTask(void *pvParameters);   //从队列里面读取数据

 
 
 int main(void)
 {
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);  
   User_GPIO_Init();
     Delay_init();
     USART_Config();
     
     /* 创建的队列用于保存最多5个值,每个数据单元都有足够的空间来存储一个long型变量 */
   xQueue = xQueueCreate( 5, sizeof( long ) );
   if(xQueue != NULL)
     {
         taskENTER_CRITICAL(); //进入临界区
    
         xTaskCreate(
                                    (TaskFunction_t        ) vSenderTask1,       //任务函数
                                    (const char *          )  "vSenderTask1",    //任务名
                                    (configSTACK_DEPTH_TYPE) SENDER1_STK_SIZE,   //堆栈大小
                                    (void *                ) 100,              //传递给任务函数的参数
                                    (UBaseType_t           ) SENDER_TASK1,  //任务优先级
                                    (TaskHandle_t *        ) &StartTask_Handler  //任务句柄
                                );
                                    

                             //创建任务Task1
                xTaskCreate((TaskFunction_t )   vSenderTask2, 
                                   (const char* )       "vSenderTask2", 
                                   (uint16_t )          SENDER2_STK_SIZE, 
                                   (void* )             200,
                                   (UBaseType_t )       SENDER_TASK2, 
                                   (TaskHandle_t* )     &Task1_Handler); 
                 
                xTaskCreate((TaskFunction_t )vReceiverTask, 
                                 (const char* )"vReceiverTask", 
                                 (uint16_t )RECEIVER_STK_SIZE, 
                                 (void* )NULL,
                                 (UBaseType_t )RECEIVER_TASK, 
                                 (TaskHandle_t* )&Task2_Handler);            
                                 
                taskEXIT_CRITICAL();            //退出临界区
        vTaskStartScheduler(); //开启任务调度
                            
     }
     else
     {
        //队列创建失败 
     }
     
 }
 
 
 void vSenderTask1(void *pvParameters)
 {
   long           lValueToSend;
   portBASE_TYPE  xStatus;
     
     lValueToSend = ( long ) pvParameters;//得到传入的数据100
     while(1)
     {
       xStatus = xQueueSendToBack( xQueue, &lValueToSend, 0 );//将数据发送到队列的队尾
         if( xStatus != pdPASS )
            {
              /* 发送操作由于队列满而无法完成 – 这必然存在错误,因为本例中的队列不可能满。 */
              printf( "Could not send to the queue.\r\n" );
            }
         
            taskYIELD();//通知调度器,不必等到时间片耗尽,切换任务
     }

 }
 
 
 //任务1
 void vSenderTask2(void *pvParameters)
 {  
   long           lValueToSend;
   portBASE_TYPE  xStatus;
     
     lValueToSend = ( long ) pvParameters;//得到传入的数据200
     while(1)
     {
       xStatus = xQueueSendToBack( xQueue, &lValueToSend, 0 );
         if( xStatus != pdPASS )
            {
              /* 发送操作由于队列满而无法完成 – 这必然存在错误,因为本例中的队列不可能满。 */
              printf( "Could not send to the queue.\r\n" );
            }
         
            taskYIELD();
     }
         
 }
 
 
  //任务2
 void vReceiverTask(void *pvParameters)
 {  
     long lReceivedValue;
   portBASE_TYPE xStatus;
     const portTickType xTicksToWait = 100;//阻塞超时时间为100ms
     
     while(1)
     {
             
      if( uxQueueMessagesWaiting( xQueue ) != 0 )
            {
              printf( "Queue should have been empty!\r\n" );
            }
            xStatus = xQueueReceive( xQueue, &lReceivedValue, xTicksToWait );
            if( xStatus == pdPASS )
      {
         printf( "Received = %ld\r\n", lReceivedValue);        
            }
            else
      {
              printf( "Could not receive from the queue.\r\n" );
            }
            
            
     }
         
 }

 

执行结果:

任务一和任务二交替将数据发送给队列,任务三把队列中的数据读取出来后串口打印。

 

posted on 2021-01-15 17:21  Darren_pty  阅读(132)  评论(0编辑  收藏  举报