• FreeRTOS学习笔记-Stream Buffer


    概述

    关键函数

    #include "freertos/stream_buffer.h"
    
    //创建stream_buffer
    StreamBufferHandle_t xStreamBufferCreate( 
    			size_t xBufferSizeBytes,//buffer 大小
    			size_t xTriggerLevelBytes );//触发大小
    			
    //查看stream_buffer有效数据量
    size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
    
    //发送stream_buffer
    size_t xStreamBufferSend( 
    			StreamBufferHandle_t xStreamBuffer,//buffer 句柄
    			const void *pvTxData, //发送数据指针
    			size_t xDataLengthBytes,//从pvTxData拷贝到stream_buffer的数据量
    			TickType_t xTicksToWait );//若stream_buffer空间不够则需要等待的时间
    //返回值: 写入stream_buffer的字节数,即便buffer空间不足,在函数退出前会尽可能写满buffer
    
    //从stream_buffer中接收数据
    size_t xStreamBufferReceive( 
    			StreamBufferHandle_t xStreamBuffer,//buffer 句柄
    			void *pvRxData,//接收数据指针
    			size_t xBufferLengthBytes,//接收的字节数
    			TickType_t xTicksToWait );//若stream_buffer为空则需要等待的时间
    
    //获取buffer可用空间
    size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    课程示例

    StreamBuffer 创建、发送与接收

    #include 
    #include "sdkconfig.h"
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "esp_system.h"
    #include "esp_spi_flash.h"
    
    
    #include "string.h"
    #include "freertos/stream_buffer.h"
    
    
    StreamBufferHandle_t sbuffer1;
    
    void mytask1(void *pvParameter)
    {
        size_t send_size;
        size_t send_len;
        char send_str[50];
        printf("task1 start \n");
        int i = 0;
        while (1)
        {
            i++;
            send_len = sprintf(send_str, "Hello World %d \n", i);
            send_size = xStreamBufferSend(
                sbuffer1,         // buffer 句柄
                (void *)send_str, //发送数据指针
                send_len,         //从pvTxData拷贝到stream_buffer的数据量
                portMAX_DELAY);   //若stream_buffer空间不够则需要等待的时间
            printf("task1 send len=%d , size = %d \n", send_len, send_size);
            vTaskDelay(pdMS_TO_TICKS(5000));
        }
    }
    
    void mytask2(void *pvParameter)
    {
        size_t rx_size;
        char rx_str[50];
        printf("task2 start \n");
        while (1)
        {
            memset(rx_str, 0, sizeof(rx_str)); //三个参数分别为:数据指针、初始化值、初始化大小
            rx_size = xStreamBufferReceive(
                sbuffer1,       // buffer 句柄
                (void *)rx_str, //接收数据指针
                sizeof(rx_str), //接收的字节数
                portMAX_DELAY); //若stream_buffer为空则需要等待的时间
            printf("task2 rx size = %d , rx str = %s\n", rx_size,rx_str);
        }
    }
    
    void app_main(void)
    {
        sbuffer1 = xStreamBufferCreate(1000, 10);
        if (sbuffer1 != NULL)
        {
            xTaskCreate(mytask1, "mytask1", 1024 * 5, NULL, 1, NULL);
            xTaskCreate(mytask2, "mytask2", 1024 * 5, NULL, 1, NULL);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    效果

    task1 start
    task2 start 
    task2 rx size = 15 , rx str = Hello World 1
    
    task1 send len=15 , size = 15
    task1 send len=15 , size = 15 
    task2 rx size = 15 , rx str = Hello World 2 
    
    task1 send len=15 , size = 15 
    task2 rx size = 15 , rx str = Hello World 3 
    
    task1 send len=15 , size = 15 
    task2 rx size = 15 , rx str = Hello World 4 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    打印接收数据有2个换行是因为发送时也加入了\n
    修改触发门限为40,效果如下:

    task1 start
    task2 start
    task1 send len=15 , size = 15
    task1 send len=15 , size = 15 
    task1 send len=15 , size = 15 
    task2 rx size = 45 , rx str = Hello World 1 
    Hello World 2
    Hello World 3
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    收满40个数据时才会触发接收。

    StreamBuffer查询接收

    #include 
    #include "sdkconfig.h"
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "esp_system.h"
    #include "esp_spi_flash.h"
    
    #include "string.h"
    #include "freertos/stream_buffer.h"
    
    StreamBufferHandle_t sbuffer1;
    
    void mytask1(void *pvParameter)
    {
        size_t send_size;
        size_t send_len;
        char send_str[50];
        printf("task1 start \n");
        int i = 0;
        while (1)
        {
            i++;
            send_len = sprintf(send_str, "Hello World %d \n", i);
            send_size = xStreamBufferSend(
                sbuffer1,         // buffer 句柄
                (void *)send_str, //发送数据指针
                send_len,         //从pvTxData拷贝到stream_buffer的数据量
                portMAX_DELAY);   //若stream_buffer空间不够则需要等待的时间
            printf("task1 send len=%d , size = %d \n", send_len, send_size);
            vTaskDelay(pdMS_TO_TICKS(5000));
        }
    }
    
    void mytask2(void *pvParameter)
    {
        size_t rx_size;
        char rx_str[50];
        printf("task2 start \n");
        while (1)
        {
            if (xStreamBufferBytesAvailable(sbuffer1) > 50)
            {
                memset(rx_str, 0, sizeof(rx_str)); //需包含:"string.h" 三个参数分别为:数据指针、初始化值、初始化大小
                rx_size = xStreamBufferReceive(
                    sbuffer1,       // buffer 句柄
                    (void *)rx_str, //接收数据指针
                    sizeof(rx_str), //接收的字节数
                    0);             //若stream_buffer为空则需要等待的时间
                printf("task2 rx size = %d , rx str = %s\n", rx_size, rx_str);
            }
            vTaskDelay(pdMS_TO_TICKS(1000));
        }
    }
    
    void app_main(void)
    {
        sbuffer1 = xStreamBufferCreate(1000, 40);
        if (sbuffer1 != NULL)
        {
            xTaskCreate(mytask1, "mytask1", 1024 * 5, NULL, 1, NULL);
            xTaskCreate(mytask2, "mytask2", 1024 * 5, NULL, 1, NULL);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    效果

    task1 start
    task2 start
    task1 send len=15 , size = 15
    task1 send len=15 , size = 15
    task1 send len=15 , size = 15
    task1 send len=15 , size = 15
    task2 rx size = 50 , rx str = Hello World 1
    Hello World 2
    Hello World 3
    Hello�?
    task1 send len=15 , size = 15
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    添加监控任务,确定StreamBuffer大小

    #include 
    #include "sdkconfig.h"
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "esp_system.h"
    #include "esp_spi_flash.h"
    
    #include "string.h"
    #include "freertos/stream_buffer.h"
    
    StreamBufferHandle_t sbuffer1;
    
    void mytask1(void *pvParameter)
    {
        size_t send_size;
        size_t send_len;
        char send_str[50];
        printf("task1 start \n");
        int i = 0;
        while (1)
        {
            i++;
            send_len = sprintf(send_str, "Hello World %d \n", i);
            send_size = xStreamBufferSend(
                sbuffer1,         // buffer 句柄
                (void *)send_str, //发送数据指针
                send_len,         //从pvTxData拷贝到stream_buffer的数据量
                portMAX_DELAY);   //若stream_buffer空间不够则需要等待的时间
            printf("task1 send len=%d , size = %d \n", send_len, send_size);
            vTaskDelay(pdMS_TO_TICKS(2000));
        }
    }
    
    void mytask2(void *pvParameter)
    {
        size_t rx_size;
        char rx_str[50];
        printf("task2 start \n");
        while (1)
        {
            if (xStreamBufferBytesAvailable(sbuffer1) >= 50)
            {
                memset(rx_str, 0, sizeof(rx_str)); //三个参数分别为:数据指针、初始化值、初始化大小
                rx_size = xStreamBufferReceive(
                    sbuffer1,       // buffer 句柄
                    (void *)rx_str, //接收数据指针
                    sizeof(rx_str), //接收的字节数
                    0);             //若stream_buffer为空则需要等待的时间
                printf("task2 rx size = %d , rx str = %s\n", rx_size, rx_str);
            }
            vTaskDelay(pdMS_TO_TICKS(1000));
        }
    }
    
    void mytask3(void *pvParameter)
    {
        size_t buffer_space;
        size_t min_space = 0;
        printf("task3 start \n");
        min_space = xStreamBufferSpacesAvailable(sbuffer1);
        while (1)
        {
            buffer_space = xStreamBufferSpacesAvailable(sbuffer1);
            if (buffer_space < min_space)
            {
                min_space = buffer_space;
            }
            printf("task3 StreamBuffer space = %d, min_space = %d \n",buffer_space,min_space);
            vTaskDelay(pdMS_TO_TICKS(1000));
        }
    }
    
    void app_main(void)
    {
        sbuffer1 = xStreamBufferCreate(1000, 40);
        if (sbuffer1 != NULL)
        {
            xTaskCreate(mytask1, "mytask1", 1024 * 5, NULL, 1, NULL);
            xTaskCreate(mytask2, "mytask2", 1024 * 5, NULL, 1, NULL);
            xTaskCreate(mytask3, "mytask3", 1024 * 5, NULL, 1, NULL);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    效果:

    task1 start
    task2 start
    task1 send len=15 , size = 15
    task3 start
    task3 StreamBuffer space = 985, min_space = 985
    task3 StreamBuffer space = 985, min_space = 985
    task1 send len=15 , size = 15
    task3 StreamBuffer space = 970, min_space = 970
    task3 StreamBuffer space = 970, min_space = 970
    task1 send len=15 , size = 15
    task3 StreamBuffer space = 955, min_space = 955
    task3 StreamBuffer space = 955, min_space = 955
    task1 send len=15 , size = 15
    task2 rx size = 50 , rx str = Hello World 1
    Hello World 2
    Hello World 3
    Hello�?
    task3 StreamBuffer space = 990, min_space = 955
    task3 StreamBuffer space = 990, min_space = 955
    task1 send len=15 , size = 15
    task3 StreamBuffer space = 975, min_space = 955
    task3 StreamBuffer space = 975, min_space = 955
    task1 send len=15 , size = 15
    task3 StreamBuffer space = 960, min_space = 955
    task3 StreamBuffer space = 960, min_space = 955
    task1 send len=15 , size = 15
    task2 rx size = 50 , rx str = World 4
    Hello World 5
    Hello World 6
    Hello Worl�?

  • 相关阅读:
    金山云回港上市:中国TO B云厂商的港股奔袭
    JMeter录制HTTPS脚本解决办法
    态势丨黑客侵扰加剧,靶场为网络安全架设“防御盾”
    windows安装VMware虚拟机(附带CentOS7部署)
    spdk用户态块层详解
    linux网络、存储性能测试
    Unity引擎更新收费模式:从收入分成转向游戏安装量,将会有哪些影响呢
    Elasticsearch学习-文档更新,可能存在的坑
    CUDA小白 - NPP(10) 图像处理 Memort Management
    ThreadLocal:多线程状态下使用ThreadLocal对全局变量进行数据隔离
  • 原文地址:https://blog.csdn.net/ai_ljh/article/details/126817128