freertos系列之队列

一、freertos队列特点:

1、数据入队出队方式:一般先进先出,也可以后进后出

2、数据传输方式:采用实际值进行传输

3、多任务访问:任何任务或中断都可以向队列发送或者读取消息

4、出队、入队阻塞:任务向队列发送消息时,设置阻塞时间,假设队列已满无法入队,

(1)阻塞时间为0:直接返回不等待

(2)阻塞时间为0-port_MAX_Delay:等待设定阻塞时间,如果等待时间之后仍然没有入队,超时后直接返回不再等待

(3)阻塞时间为port_MAX_Delay:死等,一直等到可以入队为止。

二、队列操作基本过程:

(1)创建队列

(2)往队列里面写第一个消息

(3)往队列里面写第二个消息

(4)往队列写n个消息

(5)从队列中读取第一个消息(系统会自动将第二个、第三个……第n个消息移动到第一个消息的地方)

三、实验设计:

本实验设计三个任务: start_task task1_task 、task2_task 、task3_task  这三个任务的任务功能如下:
start_task :用来创建其他 3 个任务。
task1_task :按键key0或者key1按下,键值拷贝至队列key_queue中;当按键key_up按下,将传输大数据地址到队列big_data_queue;
task2_task :读取key_queue中的消息,打印收到的键值
task3_task :从队列big_data_queue读取大数据的地址,通过地址访问大数据
代码如下:

#include "freertos_demo.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./MALLOC/malloc.h"
#include "./BSP/LED/led.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"


/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO 1                   /* 任务优先级 */
#define START_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            StartTask_Handler;  /* 任务句柄 */
void start_task(void *pvParameters);        /* 任务函数 */

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK1_PRIO      2                   /* 任务优先级 */
#define TASK1_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            Task1Task_Handler;  /* 任务句柄 */
void task1(void *pvParameters);             /* 任务函数 */

/* TASK2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK2_PRIO      3                   /* 任务优先级 */
#define TASK2_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            Task2Task_Handler;  /* 任务句柄 */
void task2(void *pvParameters);             /* 任务函数 */

/* TASK3 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK3_PRIO      4                   /* 任务优先级 */
#define TASK3_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            Task3Task_Handler;  /* 任务句柄 */
void task3(void *pvParameters);             /* 任务函数 */

/******************************************************************************************************/
List_t          TestList;                    /* 定义测试列表 */
ListItem_t         ListItem1;                    /* 定义测试列表项1 */
ListItem_t         ListItem2;                    /* 定义测试列表项2 */
ListItem_t         ListItem3;                    /* 定义测试列表项3 */

QueueHandle_t key_queue;
QueueHandle_t big_data_queue;
char buff[100]={"我是中国人,my number is 001"};

/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{
        key_queue =xQueueCreate(2,sizeof(uint8_t));
        if(key_queue != NULL)
        {
                printf("key_queue队列创建成功\r\n");
        }
        else
        {
                printf("key_queue队列创建失败\r\n");
        }
            big_data_queue = xQueueCreate(1,sizeof(char *));
        if(big_data_queue != NULL)
        {
                printf("big_data_queue队列创建成功\r\n");
        }
        else
        {
                printf("big_data_queue队列创建失败\r\n");
        }
    
    
    xTaskCreate((TaskFunction_t )start_task,            /* 任务函数 */
                (const char*    )"start_task",          /* 任务名称 */
                (uint16_t       )START_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )START_TASK_PRIO,       /* 任务优先级 */
                (TaskHandle_t*  )&StartTask_Handler);   /* 任务句柄 */
    vTaskStartScheduler();
}

/**
 * @brief       start_task
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           /* 进入临界区 */
    /* 创建任务1 */
    xTaskCreate((TaskFunction_t )task1,
                (const char*    )"task1",
                (uint16_t       )TASK1_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK1_PRIO,
                (TaskHandle_t*  )&Task1Task_Handler);
      /* 创建任务2 */
    xTaskCreate((TaskFunction_t )task2,
                (const char*    )"task2",
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler);        
              /* 创建任务3 */
    xTaskCreate((TaskFunction_t )task3,
                (const char*    )"task3",
                (uint16_t       )TASK3_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK3_PRIO,
                (TaskHandle_t*  )&Task3Task_Handler);            

    vTaskDelete(StartTask_Handler); /* 删除开始任务 */
    taskEXIT_CRITICAL();            /* 退出临界区 */
}

/*task1  
 * @brief       task1
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void task1(void *pvParameters)
{
        uint8_t key =0;
        char* buf;
        buf = buff;
        BaseType_t errorflag = 0;
    while (1)
    {
                key = key_scan(0);
                if(key == KEY0_PRES ||key == KEY1_PRES)
                {
                        errorflag =xQueueSend(key_queue,&key,portMAX_DELAY);
                        if(errorflag != pdTRUE)
                        {
                            printf("key_queue写入队列失败\r\n");
                        }
                }
                else if(key == WKUP_PRES)
                {
                        errorflag =xQueueSend(big_data_queue,&buf,portMAX_DELAY);
                        if(errorflag != pdTRUE)
                        {
                            printf("big_data_queue写入队列失败\r\n");
                        }
                }
                vTaskDelay(10);
    }
        
}


/*task2
 * @brief       task2
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void task2(void *pvParameters)
{        
        uint8_t key = 0;
        BaseType_t errorflag = 0;
        while(1)
        {
            errorflag = xQueueReceive(key_queue,&key,portMAX_DELAY);
            if(errorflag != pdTRUE)
                {
                    printf("key_queue读取队列失败\r\n");
                }
            else
            {
                    printf("key_queue读取队列成功,数据:%d\r\n",key);
            }
        }
        
}


/*task3
 * @brief       task3
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void task3(void *pvParameters)
{
    uint8_t key = 0;
    char* buf;
    BaseType_t errorflag = 0;
    buf = buff;
    while(1)
    {
        errorflag = xQueueReceive(big_data_queue,&buf,portMAX_DELAY);
        if(errorflag != pdTRUE)
        {
            printf("big_data_queue读取队列失败\r\n");
        }
        else
        {
                printf("big_data_queue读取队列成功,数据:%s\r\n",buf);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值