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 阅读(134) 评论(0) 编辑 收藏 举报