新路程------循环buf的实现

#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);

猜你喜欢

转载自blog.csdn.net/u013308744/article/details/78945508