栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

microQueue

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

microQueue

队列是程序当中最常见的一个组件,特别是在嵌入式软件开发,一个好用的队列既能够保证数据传输的稳定,还能实现代码的适当解耦,本文以单片机为平台,介绍开源microQueue库的原理与使用。

git厂库:https://gitee.com/honrun_he/gd32-w51x_-templates.git

microQueue简介

microQueue是一款环形FIFO,可自由配置每个队列的长度、可设置溢出为锁定模式、覆盖模式。

结构体如下:

typedef enum {
    queueModeNormal = 0,    
    queueModeLock,          
}enumQueueMode;

typedef struct{
    char *pcName;

    uint8_t *pHead;
    uint8_t *pTail;
    uint8_t *pReadFrom;
    uint8_t *pWriteTo;

    int32_t length;

    enumQueueMode mode;
}QueueType;

结构体成员解释:

pHead:指向列队RAM的第1个字节;

pTail:指向队列的尾部再加1个字节(每当pReadFrom、pWriteTo等于pTail时,把pReadFrom、pWriteTo再指向pHead);

pReadFrom:指向队列当前可以读取的字节(每出队1个字节,值+1);

pWriteTo:指向队列当前可以写入的字节(每入队1个字节,值+1);

length:队列长度;

直线显示

环形显示

源码:

#include "stdint.h"
#include "stdio.h"
#include "string.h"
#include "DevicesQueue.h"


QueueType g_TypeQueueUart0Read = {0};
static uint8_t st_ucQueueUart0ReadBuff[QUEUE_UART0_READ_LENGTH + 4] = {0};
QueueType g_TypeQueueUart1Read = {0};
static uint8_t st_ucQueueUart1ReadBuff[QUEUE_UART1_READ_LENGTH + 4] = {0};
QueueType g_TypeQueueUart2Read = {0};
static uint8_t st_ucQueueUart2ReadBuff[QUEUE_UART2_READ_LENGTH + 4] = {0};

QueueType g_TypeQueueKeyInput = {0};
static uint8_t st_ucQueueKeyInputBuff[QUEUE_KEY_INPUT_LENGTH + 4] = {0};


enumQueueState enumQueueInit(void)
{
    enumQueueState enumState = queueNormal;
    int8_t i = 0;


    if(enumQueueCreate(&g_TypeQueueUart0Read, "Uart0 Read", st_ucQueueUart0ReadBuff, QUEUE_UART0_READ_LENGTH, queueModeLock) != queueNormal)
        enumState = queueError;
    if(enumQueueCreate(&g_TypeQueueUart1Read, "Uart1 Read", st_ucQueueUart1ReadBuff, QUEUE_UART1_READ_LENGTH, queueModeLock) != queueNormal)
        enumState = queueError;
    if(enumQueueCreate(&g_TypeQueueUart2Read, "Uart2 Read", st_ucQueueUart2ReadBuff, QUEUE_UART2_READ_LENGTH, queueModeLock) != queueNormal)
        enumState = queueError;

    if(enumQueueCreate(&g_TypeQueueKeyInput, "Key Input",   st_ucQueueKeyInputBuff, QUEUE_KEY_INPUT_LENGTH, queueModeNormal) != queueNormal)
        enumState = queueError;


    if(enumState != queueNormal)
        printf("enumQueueInit error.rn");


    return enumState;
}


enumQueueState enumQueueCreate(QueueType *pTypeQueue, char *pcName, uint8_t *pucBuff, int32_t iLength, enumQueueMode enumMode)
{
    if(pTypeQueue == NULL)
        return queueNull;

    if(iLength < 1)
        return queueEmpty;

    pTypeQueue->pcName    = pcName;
    pTypeQueue->pHead     = pucBuff;
    pTypeQueue->length    = iLength + 1;
    pTypeQueue->pReadFrom = pTypeQueue->pHead;
    pTypeQueue->pWriteTo  = pTypeQueue->pHead;
    pTypeQueue->pTail     = pTypeQueue->pHead + pTypeQueue->length;
    pTypeQueue->mode      = enumMode;

    return queueNormal;
}


enumQueueState enumQueueGetState(QueueType *pTypeQueue)
{
    uint8_t * pNow = NULL;

    if((pTypeQueue == NULL) || (pTypeQueue->pHead == NULL))
      return queueNull;

    if(pTypeQueue->pReadFrom == pTypeQueue->pWriteTo)
      return queueEmpty;

    pNow = pTypeQueue->pWriteTo + 1;
    pNow = (pNow >= pTypeQueue->pTail) ? pTypeQueue->pHead : pNow;

    if(pNow == pTypeQueue->pReadFrom)
      return queueFull;

    return queueNormal;
}


enumQueueState enumQueueSetState(QueueType *pTypeQueue, enumQueueState enumState)
{
    if((pTypeQueue == NULL) || (pTypeQueue->pHead == NULL))
        return queueNull;

    switch(enumState)
    {
        case queueEmpty:
            memset(pTypeQueue->pHead, 0, pTypeQueue->length);
            pTypeQueue->pReadFrom = pTypeQueue->pWriteTo = pTypeQueue->pHead;
            break;

        default : break;
    }

    return queueNormal;
}


static void *vQueueMemrchr(void *pvHandle, uint8_t ucValue, int32_t iCount)
{
    uint8_t *pucCheck = pvHandle;

    pucCheck += iCount - 1;

    while((iCount--) > 0)
    {
        if(*pucCheck == ucValue)
            return pucCheck;

        --pucCheck;
    }

    return NULL;
}


int32_t iQueueGetLengthOfOccupy(QueueType *pTypeQueue)
{
    int32_t iLength = 0;

    if((pTypeQueue == NULL) || (pTypeQueue->pHead == NULL))
        return 0;

    if(pTypeQueue->pReadFrom <= pTypeQueue->pWriteTo)
        iLength = pTypeQueue->pWriteTo - pTypeQueue->pReadFrom;
    else
        iLength = pTypeQueue->length - (pTypeQueue->pReadFrom - pTypeQueue->pWriteTo);

    return iLength;
}


int32_t iQueueGetLengthOfOccupyNeed(QueueType *pTypeQueue, uint8_t ucByte)
{
    int32_t iLength = 0;
    uint8_t *pucHead = NULL;

    if((pTypeQueue == NULL) || (pTypeQueue->pHead == NULL))
        return 0;

    
    if(pTypeQueue->pReadFrom <= pTypeQueue->pWriteTo)
    {
        if((pucHead = vQueueMemrchr(pTypeQueue->pReadFrom, ucByte, pTypeQueue->pWriteTo - pTypeQueue->pReadFrom)) != NULL)
            iLength = (pucHead - pTypeQueue->pReadFrom) + 1;
    }
    
    else
    {
        
        if((pucHead = vQueueMemrchr(pTypeQueue->pHead, ucByte, pTypeQueue->pWriteTo - pTypeQueue->pHead)) != NULL)
            iLength = (pucHead - pTypeQueue->pHead) + (pTypeQueue->pTail - pTypeQueue->pReadFrom) + 1;

        
        else if((pucHead = vQueueMemrchr(pTypeQueue->pReadFrom, ucByte, pTypeQueue->pTail - pTypeQueue->pReadFrom)) != NULL)
            iLength = (pucHead - pTypeQueue->pReadFrom) + 1;
    }

    return iLength;
}


int32_t iQueueGetLengthOfSeparetor(QueueType *pTypeQueue, uint8_t ucByte)
{
    int32_t iLength = 0;
    uint8_t *pucHead = NULL;

    if((pTypeQueue == NULL) || (pTypeQueue->pHead == NULL))
        return 0;

    
    if(pTypeQueue->pReadFrom <= pTypeQueue->pWriteTo)
    {
        if((pucHead = memchr(pTypeQueue->pReadFrom, ucByte, pTypeQueue->pWriteTo - pTypeQueue->pReadFrom)) != NULL)
            iLength = (pucHead - pTypeQueue->pReadFrom) + 1;
    }
    
    else
    {
        
        if((pucHead = memchr(pTypeQueue->pReadFrom, ucByte, pTypeQueue->pTail - pTypeQueue->pReadFrom)) != NULL)
            iLength = (pucHead - pTypeQueue->pReadFrom) + 1;

        
        else if((pucHead = memchr(pTypeQueue->pHead, ucByte, pTypeQueue->pWriteTo - pTypeQueue->pHead)) != NULL)
            iLength = (pucHead - pTypeQueue->pHead) + (pTypeQueue->pTail - pTypeQueue->pReadFrom) + 1;
    }

    return iLength;
}


int32_t iQueueGetLengthOfRemaining(QueueType *pTypeQueue)
{
    int32_t iLength = 0;

    if((pTypeQueue == NULL) || (pTypeQueue->pHead == NULL))
        return 0;

    if(pTypeQueue->pReadFrom <= pTypeQueue->pWriteTo)
        iLength = pTypeQueue->length - (pTypeQueue->pWriteTo - pTypeQueue->pReadFrom) - 1;
    else
        iLength = (pTypeQueue->pReadFrom - pTypeQueue->pWriteTo) - 1;

    return iLength;
}


enumQueueState enumQueuePushByte(QueueType *pTypeQueue, uint8_t ucData)
{
    enumQueueState enumPushState = queueNormal;

    if((pTypeQueue == NULL) || (pTypeQueue->pHead == NULL))
        return queueNull;

    if(enumQueueGetState(pTypeQueue) == queueFull)
    {
        printf("pTypeQueue %s full!rn", pTypeQueue->pcName);

        if(pTypeQueue->mode == queueModeLock)
            return queueFull;

        enumPushState = queueFull;
    }

    *pTypeQueue->pWriteTo++ = ucData;
    pTypeQueue->pWriteTo = ((pTypeQueue->pWriteTo >= pTypeQueue->pTail) ? pTypeQueue->pHead : pTypeQueue->pWriteTo);

    
    if(enumPushState == queueFull)
    {
        pTypeQueue->pReadFrom = pTypeQueue->pWriteTo + 1;
        pTypeQueue->pReadFrom = ((pTypeQueue->pReadFrom >= pTypeQueue->pTail) ? pTypeQueue->pHead : pTypeQueue->pReadFrom);
    }

    return enumPushState;
}


enumQueueState enumQueuePopByte(QueueType *pTypeQueue, uint8_t *pucData)
{
    if((pTypeQueue == NULL) || (pTypeQueue->pHead == NULL))
        return queueNull;

    if(pTypeQueue->pReadFrom == pTypeQueue->pWriteTo)
      return queueEmpty;

    *pucData = *pTypeQueue->pReadFrom++;
    pTypeQueue->pReadFrom = ((pTypeQueue->pReadFrom >= pTypeQueue->pTail) ? pTypeQueue->pHead : pTypeQueue->pReadFrom);

    return queueNormal;
}


enumQueueState enumQueueViewByte(QueueType *pTypeQueue, uint8_t *pucData)
{
    if((pTypeQueue == NULL) || (pTypeQueue->pHead == NULL))
        return queueNull;

    if(pTypeQueue->pReadFrom == pTypeQueue->pWriteTo)
      return queueEmpty;

    *pucData = *pTypeQueue->pReadFrom;

    return queueNormal;
}


enumQueueState enumQueuePushDatas(QueueType *pTypeQueue, void *pvBuff, int32_t iLength)
{
    uint8_t *pucHandle = pvBuff;
    enumQueueState enumPushState = queueNormal;

    if((pTypeQueue == NULL) || (pTypeQueue->pHead == NULL))
        return queueNull;

    if(iQueueGetLengthOfRemaining(pTypeQueue) < iLength)
    {
        printf("pTypeQueue %s full!rn", pTypeQueue->pcName);

        if(pTypeQueue->mode == queueModeLock)
            return queueFull;

        enumPushState = queueFull;
    }

    while((iLength--) > 0)
    {
        *pTypeQueue->pWriteTo++ = *pucHandle++;
        pTypeQueue->pWriteTo = ((pTypeQueue->pWriteTo >= pTypeQueue->pTail) ? pTypeQueue->pHead : pTypeQueue->pWriteTo);
    }

    
    if(enumPushState == queueFull)
    {
        pTypeQueue->pReadFrom = pTypeQueue->pWriteTo + 1;
        pTypeQueue->pReadFrom = ((pTypeQueue->pReadFrom >= pTypeQueue->pTail) ? pTypeQueue->pHead : pTypeQueue->pReadFrom);
    }

    return enumPushState;
}


enumQueueState enumQueuePopDatas(QueueType *pTypeQueue, void *pvBuff, int32_t iLength)
{
    uint8_t *pucHandle = pvBuff;

    if((pTypeQueue == NULL) || (pTypeQueue->pHead == NULL))
        return queueNull;

    if(pvBuff == NULL)
        return queueError;

    if(iQueueGetLengthOfOccupy(pTypeQueue) < iLength)
        return queueError;

    while((iLength--) > 0)
    {
        *pucHandle++ = *pTypeQueue->pReadFrom++;
        pTypeQueue->pReadFrom = ((pTypeQueue->pReadFrom >= pTypeQueue->pTail) ? pTypeQueue->pHead : pTypeQueue->pReadFrom);
    }

    return queueNormal;
}


enumQueueState enumQueueViewDatas(QueueType *pTypeQueue, void *pvBuff, int32_t iLength)
{
    uint8_t *pucHandle = pvBuff, *pucReadFrom = pTypeQueue->pReadFrom;

    if((pTypeQueue == NULL) || (pTypeQueue->pHead == NULL))
        return queueNull;

    if(pvBuff == NULL)
        return queueError;

    if(iQueueGetLengthOfOccupy(pTypeQueue) < iLength)
        return queueError;

    while((iLength--) > 0)
    {
        *pucHandle++ = *pucReadFrom++;
        pucReadFrom = ((pucReadFrom >= pTypeQueue->pTail) ? pTypeQueue->pHead : pucReadFrom);
    }

    return queueNormal;
}


enumQueueState enumQueuePopDatasNeed(QueueType *pTypeQueue, void *pvBuff, int32_t iLength, uint8_t ucByte)
{
    uint8_t *pucHandle = pvBuff;

    if((pTypeQueue == NULL) || (pTypeQueue->pHead == NULL))
        return queueNull;

    if(pvBuff == NULL)
        return queueError;

    if(iQueueGetLengthOfOccupyNeed(pTypeQueue, ucByte) < iLength)
        return queueError;

    while((iLength--) > 0)
    {
        *pucHandle++ = *pTypeQueue->pReadFrom++;
        pTypeQueue->pReadFrom = ((pTypeQueue->pReadFrom >= pTypeQueue->pTail) ? pTypeQueue->pHead : pTypeQueue->pReadFrom);
    }

    return queueNormal;
}


enumQueueState enumQueueViewDatasNeed(QueueType *pTypeQueue, void *pvBuff, int32_t iLength, uint8_t ucByte)
{
    uint8_t *pucHandle = pvBuff, *pucReadFrom = pTypeQueue->pReadFrom;

    if((pTypeQueue == NULL) || (pTypeQueue->pHead == NULL))
        return queueNull;

    if(pvBuff == NULL)
        return queueError;

    if(iQueueGetLengthOfOccupyNeed(pTypeQueue, ucByte) < iLength)
        return queueError;

    while((iLength--) > 0)
    {
        *pucHandle++ = *pucReadFrom++;
        pucReadFrom = ((pucReadFrom >= pTypeQueue->pTail) ? pTypeQueue->pHead : pucReadFrom);
    }

    return queueNormal;
}

头文件:

#ifndef _DevicesQueue_H_
#define _DevicesQueue_H_



#define QUEUE_MAX_LENGTH         (2048)

#define QUEUE_UART0_READ_LENGTH  (1024)
#define QUEUE_UART1_READ_LENGTH  (1024)
#define QUEUE_UART2_READ_LENGTH  (1024)

#define QUEUE_KEY_INPUT_LENGTH   (256)
#define QUEUE_KEY_TOUCH_LENGTH   (64)





#define queueRoundUp(x, n) (((x) + (n) - 1) & (~((n) - 1)))


typedef enum {
    queueNormal = 0,
    queueError,
    queueNull,
    queueEmpty,
    queueFull,
}enumQueueState;

typedef enum {
    queueModeNormal = 0,    
    queueModeLock,          
}enumQueueMode;



typedef struct{
    char *pcName;

    uint8_t *pHead;
    uint8_t *pTail;
    uint8_t *pReadFrom;
    uint8_t *pWriteTo;

    int32_t length;

    enumQueueMode mode;
}QueueType;



extern QueueType g_TypeQueueUart0Read;
extern QueueType g_TypeQueueUart1Read;
extern QueueType g_TypeQueueUart2Read;

extern QueueType g_TypeQueueKeyInput;



enumQueueState enumQueueInit(void);
enumQueueState enumQueueCreate(QueueType *pTypeQueue, char *pcName, uint8_t *pucBuff, int32_t iLength, enumQueueMode enumMode);
enumQueueState enumQueueGetState(QueueType *pTypeQueue);
enumQueueState enumQueueSetState(QueueType *pTypeQueue, enumQueueState enumState);
int32_t iQueueGetLengthOfOccupy(QueueType *pTypeQueue);
int32_t iQueueGetLengthOfOccupyNeed(QueueType *pTypeQueue, uint8_t ucByte);
int32_t iQueueGetLengthOfSeparetor(QueueType *pTypeQueue, uint8_t ucByte);
int32_t iQueueGetLengthOfRemaining(QueueType *pTypeQueue);
enumQueueState enumQueuePushByte(QueueType *pTypeQueue, uint8_t ucData);
enumQueueState enumQueuePopByte(QueueType *pTypeQueue, uint8_t *pucData);
enumQueueState enumQueueViewByte(QueueType *pTypeQueue, uint8_t *pucData);
enumQueueState enumQueuePushDatas(QueueType *pTypeQueue, void *pvBuff, int32_t iLength);
enumQueueState enumQueuePopDatas(QueueType *pTypeQueue, void *pvBuff, int32_t iLength);
enumQueueState enumQueueViewDatas(QueueType *pTypeQueue, void *pvBuff, int32_t iLength);
enumQueueState enumQueuePopDatasNeed(QueueType *pTypeQueue, void *pvBuff, int32_t iLength, uint8_t ucByte);
enumQueueState enumQueueViewDatasNeed(QueueType *pTypeQueue, void *pvBuff, int32_t iLength, uint8_t ucByte);

#endif

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/923295.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号