[其它应用] 循环队列KFIFO

[复制链接]
144|0
Xiashiqi 发表于 2025-10-9 21:49 | 显示全部楼层 |阅读模式
根据linux的kfifo改写而来,无锁,用于MCU,比如异步打印调试信息,MCU串口通信等。

#ifndef _KFIFO_H_
#define _KFIFO_H_

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

struct KFIFO{   
        unsigned char *buffer;    /* the buffer holding the data */   
        unsigned int size;        /* the size of the allocated buffer */   
        unsigned int in;          /* data is added at offset (in % size) */   
        unsigned int out;         /* data is extracted from off. (out % size) */   
};

unsigned int kfifo_init(struct KFIFO *fifo, unsigned char *buffer, unsigned int len);
unsigned int kfifo_put(struct KFIFO *fifo, unsigned char *buffer, unsigned int len);
unsigned int kfifo_get(struct KFIFO *fifo, unsigned char *buffer, unsigned int len);
uint32_t kfifo_len(struct KFIFO fifo);
uint8_t kfifo_is_empty(struct KFIFO fifo);
uint8_t kfifo_is_full(struct KFIFO fifo);
uint32_t kfifo_avail(struct KFIFO fifo);

#endif



#include "kfifo.h"

#define min(a, b)                (((a) < (b)) ? (a) : (b))



unsigned int is_power_of_2(unsigned int n){
        return (n != 0 && (n & (n-1) == 0));   
}  

unsigned int kfifo_init(struct KFIFO *fifo, unsigned char *buffer, unsigned int len){
        if(!is_power_of_2(len))
                return 0;
        fifo->in = 0;
        fifo->out = 0;
        fifo->size = len;
        fifo->buffer = buffer;
        return len;   
}  

/**
* @description: 注意len超过剩余空间的部分会丢失
* @param {KFIFO} *fifo
* @param {unsigned char} *buffer
* @param {unsigned int} len
* @return {*}
*/
unsigned int kfifo_put(struct KFIFO *fifo, unsigned char *buffer, unsigned int len){
        unsigned int L;
        len = min(len , fifo->size - fifo->in + fifo->out );
        L = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
        memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, L);   
        memcpy(fifo->buffer, buffer + L, len - L);
        fifo->in += len;
        return len;   
}  

unsigned int kfifo_get(struct KFIFO *fifo, unsigned char *buffer, unsigned int len){
        unsigned int L;
        len = min(len, fifo->in - fifo->out);
        L = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
        memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), L);
        memcpy(buffer + L, fifo->buffer, len - L);
        fifo->out += len;
        return len;
}

// kfifo_len - returns the number of used elements in the fifo
uint32_t kfifo_len(struct KFIFO fifo)
{
    return (fifo->in - fifo->out);
}

// kfifo_is_empty - returns true if the fifo is empty
uint8_t kfifo_is_empty(struct KFIFO fifo)
{
    return (fifo->in == fifo->out);
}

// kfifo_is_full - returns true if the fifo is full
uint8_t kfifo_is_full(struct KFIFO fifo)
{
    return ((fifo->in - fifo->out) > (fifo->size - 1));
}

// kfifo_avail - returns the number of unused elements in the fifo
uint32_t kfifo_avail(struct KFIFO fifo)
{
    return (fifo->size - (fifo->in - fifo->out));
}


————————————————
版权声明:本文为CSDN博主「sscb0521」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sscb0521/article/details/143805198

您需要登录后才可以回帖 登录 | 注册

本版积分规则

97

主题

282

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部