循环队列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));
}