#define RING_BUF_EMPTY 0
#define RING_BUF_NOTEMPTY 1
#define RING_BUF_RING 1
#define RING_BUF_NORING 0
struct ring_buf {
char *buf;
int head;
int tail;
int size; //size of buf
int rx_flag; //indecate whether buf have data
int ring; // indecate head over buf end
};
#include <linux/module.h>
#include <linux/init.h>#include <linux/pci.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/tty.h>
#include <linux/serial_core.h>
#include <linux/8250_pci.h>
#include <linux/bitops.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include "ringbuf.h"
int ring_buf_empty(struct ring_buf * tmp)
{
if (tmp->head == tmp->tail) {
return RING_BUF_EMPTY;
} else {
return RING_BUF_NOTEMPTY;
}
}
EXPORT_SYMBOL_GPL(ring_buf_empty);
int ring_buf_put(int len, char* src, struct ring_buf * tmp)
{
int i = 0;
for (i = 0; i < len; i++) {
tmp->buf[tmp->tail] = src[i];
tmp->tail = ((tmp->tail + 1) & (tmp->size - 1));
if(tmp->tail == tmp->head ){
tmp->ring = RING_BUF_RING ;
}
}
tmp->rx_flag = RING_BUF_NOTEMPTY ;
return i;
}
EXPORT_SYMBOL_GPL(ring_buf_put);
int ring_buf_get(char* des, struct ring_buf * tmp)
{
int i = 0;
int len = 0;
if (tmp->rx_flag != RING_BUF_EMPTY) { //首先判断buf是否为空,也就是上面put的时候要有个标志位去记录是否有数据写入过
if (tmp->tail == tmp->head) { //如果不为空,而且head=tail,则判断tail是否为0,然后决定get的起始位置
len = tmp->size ; //长度都是size
if (tmp->tail == 0) {
memcpy(des, &tmp->buf[0], tmp->size);
} else { //ring
for (i = 0; i < tmp->size; i++ ) {
des[i] = tmp->buf[tmp->tail];
tmp->tail = ((tmp->tail + 1) & (tmp->size - 1));
}
}
}else{
if (tmp->ring == RING_BUF_RING) { //设置一个flag记录tail是否超过head后又写到bud的头部,如果这样,则无论如何都是从tail读取一圈
len = tmp->size;
for (i = 0; i< tmp->size; i++) {
des[i] = tmp->buf[tmp->tail];
tmp->tail = ((tmp->tail + 1) & (tmp->size - 1));
}
} else {
if (tmp->tail > tmp->head) { //如果没有写过一圈,则长度就是tail -head或者下面的size-head+tail
len = tmp->tail - tmp->head;
memcpy(des, &tmp->buf[tmp->head], len);
}else{
len = tmp->size-tmp->head+tmp->tail;
for (i = 0; i<len; i++ ) {
des[i] = tmp->buf[tmp->head];
tmp->head = ((tmp->head + 1) & (tmp->size - 1));
}
}
}
}
}else{
printk("cc1101 rx_cir_buf no data\n");
return len;
}
tmp->head = tmp->tail; //每次读完都要让head=tail,而且恢复标志位为0
tmp->rx_flag = RING_BUF_EMPTY;
tmp->ring = RING_BUF_NORING;
return len;
}
EXPORT_SYMBOL_GPL(ring_buf_get);