zoukankan      html  css  js  c++  java
  • 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.
    " );
                }
             
                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.
    " );
                }
             
                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!
    " );
                }
                xStatus = xQueueReceive( xQueue, &lReceivedValue, xTicksToWait );
                if( xStatus == pdPASS )
          {
             printf( "Received = %ld
    ", lReceivedValue);        
                }
                else
          {
                  printf( "Could not receive from the queue.
    " );
                }
                
                
         }
             
     }

    执行结果:

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

  • 相关阅读:
    数据库产生的背景
    VS2008执行MFC程序,提示microsoft incremental linker已停止工作解决方法
    leetcode第一刷_Add Binary
    【MongoDB】深入了解MongoDB不可不知的十点
    哈理工2015暑假训练赛 zoj 2078Phone Cell
    dpdk l2fwd 应用流程分析
    在Redhat Linux中执行非Redhat的Openstack, Redhat将对其Linux不提供支持
    Wing IDE 怎样设置 python版本号
    Shell编程入门
    通达OA 小飞鱼OA实施法:以项目管理的方式来推进工作流设计项目实施
  • 原文地址:https://www.cnblogs.com/darren-pty/p/14283203.html
Copyright © 2011-2022 走看看