**循环缓冲fifo是先进先出的。生产者和消费者都只有一个,linux系统下使用提供了一种免锁的机制,处理时不用加锁。**UART下收发fifo主要是解决收发中断过于频繁,会导致CPU效率不高。
#include<stdio.h>struct cycle_fifo_t{int *fifo_ptr;//数据缓冲的起始位置volatile int rd;//读指针的地址volatile int wr;//写指针的地址int fifo_buffer;//数据区的大小};enum isr_name_t{second = 0,//秒任务的中断button, //按键的中断};enum isr_name_t isr_name;//中断向量名struct cycle_fifo_t isr_fifo;//中断向量的双向循环fifo//void fifo_init(struct cycle_fifo_t *fifo, void *buffer, int len){fifo->fifo_ptr = buffer;//指向同一片内存地址fifo->rd = 0;fifo->wr = 0;fifo->fifo_buffer = len;} //往fifo里面存放中断向量名void fifo_put_byte(struct cycle_fifo_t *fifo, int isr_name){//首先判断下fifo还有没有空间可以写if (fifo_get_free_byte(fifo)){fifo->fifo_ptr[fifo->wr] = isr_name;}if (++fifo->wr == fifo->fifo_buffer)//fifo缓存的内容写到头了,需要从头开始写{fifo->wr = 0;}}//从fifo里面读存放的数据int fifo_get_byte(struct cycle_fifo_t *fifo ,int *read_data,int read_len){if ( read_len > fifo_get_used_byte(fifo)){read_len = fifo_get_used_byte(fifo);//最多只能将存入的数据全部读出来}while (read_len--){read_data[read_len] = fifo->fifo_ptr[fifo->rd++]; //采用先进先出的原则if (fifo->rd > fifo->fifo_buffer){fifo->rd = 0;//则从数据的起始地址重新读return 1;}}}//获取读和写指针长度的差值 int fifo_get_used_byte(struct cycle_fifo_t *fifo){int num = 0;//要考虑两种情况,一种是读的地址大于写的地址,说明写已经反转从头开始了,一种是正常的读指针小于写指针if(fifo->wr >= fifo->rd){num = fifo->wr - fifo->rd;}else{num = fifo->fifo_buffer - (fifo->rd - fifo->wr);}return num;}//求剩余多少fifo空间还可以使用int fifo_get_free_byte(struct cycle_fifo_t *fifo){return fifo->fifo_buffer - fifo_get_used_byte(fifo);//总的fifo长度资源 - 已经使用过的资源}int isr_fifo_buffer[100] = { 0 };//中断向量的缓存int main(){//int buf[50] = { 0 };int get_data = 0 ;//获取fifo中存入的数据fifo_init(&isr_fifo, isr_fifo_buffer, 100);//申请fifo空间的大小//isr_name = button;isr_name = 8;fifo_put_byte(&isr_fifo, isr_name);//将按键的中断号写入到fifo中fifo_get_byte(&isr_fifo, &get_data, 1);printf("%d\n", get_data);system("pause");}