循环队列KFIFO

根据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));
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值