FreeRTOS【13】流缓冲区使用

1.开发背景

        基于以上的章节,了解了 FreeRTOS 多线程间的信号量、队列的使用,已经满足了日常使用场景。其中,队列的使用规定了队伍成员的大小,然而现实使用场景下,很多数据不都是定长大小了,例如不定长的通讯协议亦或者是缓存日志信息,如果在这种场景下使用队列传递信息显然不合适,会导致队伍中空间没有利用起来。因此,FreeRTOS 引入流缓冲区,实际上就是环形缓存。

        注意:流缓冲区相对于队列没有设置临界区保护,只有一对一传输才是安全的,一对多或者多对多需要自行进入临界区保护。

2.开发需求

        设计实验:

        1)创建 2 个线程,控制线程和接收线程

        2)控制线程定时发送数据到流缓存区

        3)接收线程接收流缓存区的数据

3.开发环境

        window10 + MDK + STM32F429 + FreeRTOS10.3.1

4.实现步骤

4.1 实现编码

        创建流缓存区还需要注意的是,触发的字节数 xTriggerLevelBytes,接收数据的时候需要达到触发字节数才会触发接收,一般设置为 1 即可。

#include "appTest.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "mspDwt.h"
#include "mspGpio.h"
#include "mspExti.h"

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "stream_buffer.h"

#include "appLog.h"

typedef struct
{
    /* 流缓存区 */
    unsigned char rxBuff[1024];
    StreamBufferHandle_t  buffer;
    
    /* 创建任务 */
    TaskHandle_t taskCtrl;
    TaskHandle_t taskRx;      
    
}Ctrl_t;

/* 文件指针 */
static Ctrl_t s_ctrl = {0};
static Ctrl_t *p = &s_ctrl;
static void TaskCtrl(void *pvParameters);
static void TaskRx(void *pvParameters);

static void TaskCtrl(void *pvParameters)
{
    for ( ; ; )
    {
        static unsigned char count = 0;
        vTaskDelay(10);
        
        if (count < 10)
        {
            xStreamBufferSend(p->buffer, &count, sizeof(count), portMAX_DELAY);
            Log_Debug("%s Tx Data = %d\r\n", __func__, count);
            count++;
        }
    }
}

/* 接收线程 */
static void TaskRx(void *pvParameters)
{
    for ( ; ; )
    {
        size_t rxSize = xStreamBufferReceive(p->buffer, p->rxBuff, 100, portMAX_DELAY);
        
        Log_Debug("%s RxData = ", __func__);
        for (int i = 0; i < rxSize; i++)
        {
            Log(eLog_Debug, "%.2X ", p->rxBuff[i]);
        }
        Log(eLog_Debug, "\r\n");
    }
}

/* 测试初始化 */
void aTest_Init(void)
{
    /* 创建流缓冲区 */
    size_t xBufferSizeBytes = 100;
    size_t xTriggerLevelBytes = 1;  // 接收的字节大于触发字节可以提前唤醒
    p->buffer = xStreamBufferCreate(xBufferSizeBytes, xTriggerLevelBytes);
    
    /* 创建动态任务 */
    xTaskCreate(TaskCtrl, "TaskCtrl",  500, NULL, 4, &p->taskCtrl);
    xTaskCreate(TaskRx,   "TaskRx",    500, NULL, 4, &p->taskRx);
}

/* Key2 PC13   Key0 PH3 Key1 PH2 */
void Exti13_TriggerInterrupt(void)
{
    mspExti_Close(13);
    
    if (mspGpio_GetInput("PC13") == 0)
    {
        
    }
}

4.2 结果显示

4.3 其他常用接口

xStreamBufferIsEmpty                // 判断缓存是否空
xStreamBufferIsFull                 // 判断缓存是否满
xStreamBufferReset                  // 缓存复位清空
xStreamBufferBytesAvailable         // 缓存现有已存储字节
xStreamBufferSpacesAvailable        // 混存现有未储存字节
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值