Recently, the author needed C language to implement a FIFO when working on a project, and started to refer to the following codes of these two masters.
Great God One:
C language to implement FIFO code_c language fifo-CSDN blog
Great God Two:
C language to implement FIFO code_c language fifo-CSDN blog
Combining the advantages and disadvantages of the code written by the two masters, I added the is_empty member variable on the basis of the master one to implement a ring FIFO. Write first and then read. If it is full, you cannot write again. If it is empty, you cannot read again.
The fifo.c file code is as follows:
#include "fifo.h" #include "xil_types.h" /** * @brief fifo structure */ typedef struct { int ptr_write; int ptr_read; bool is_full; bool is_empty; //The number of elements stored in fifo, not the byte size int item_sum; //Element size. Unit: bytes int item_size; void *fifo_ptr; }Fifo; int FifoAddr; /** * @brief Create fifo * @param item_sum: the number of elements in fifo. Note that it is not the number of bytes * @param item_size: element size. Unit: bytes * @return fifo index */ int fifo_create(int item_sum, int item_size) { Fifo *fifo = (Fifo *)malloc(sizeof(Fifo)); fifo->item_sum = item_sum; fifo->item_size = item_size; fifo->ptr_write = 0; fifo->ptr_read = 0; fifo->is_full = false; fifo->is_empty = true; fifo->fifo_ptr = (void *)malloc(item_sum * item_size); if(NULL == fifo->fifo_ptr) { xil_printf("malloc failed"); } return (int)fifo; } /** * @brief delete fifo * @param fifo_index: fifo index */ void fifo_delete(int fifo_index) { Fifo *fifo = (Fifo *)fifo_index; free(fifo->fifo_ptr); fifo->fifo_ptr = NULL; free(fifo); fifo = NULL; } /** * @brief fifo checks whether it can be written * @param fifo_index: fifo index * @retval false: cannot be written. true: can be written */ bool fifo_writeable(int fifo_index) { Fifo *fifo = (Fifo *)fifo_index; return !fifo->is_full; } /** * @brief fifo writing * @param fifo_index: fifo index * @param frame: write element pointer * @return false:failure.true:success */ bool fifo_write(int fifo_index, void *data) { Fifo *fifo = (Fifo *)fifo_index; if (fifo->is_full) { return false; } memcpy((char *)(fifo->fifo_ptr) + fifo->ptr_write * fifo->item_size, data, fifo->item_size); fifo->ptr_write + + ; if (fifo->ptr_write >= fifo->item_sum) { fifo->ptr_write = 0; } fifo->is_empty = false; if (fifo->ptr_write == fifo->ptr_read) { fifo->is_full = true; } return true; } /** * @brief fifo batch writing * @param fifo_index: fifo index * @param data: write element pointer * @param item_num: the number of elements written * @return false:failure.true:success */ bool fifo_write_batch(int fifo_index, void *data, int item_num) { Fifo *fifo = (Fifo *)fifo_index; if (fifo_writeable_item_count((int)fifo) < item_num) { return false; } memcpy((char *)(fifo->fifo_ptr) + fifo->ptr_write * fifo->item_size, data, fifo->item_size * item_num); fifo->ptr_write + = item_num; if (fifo->ptr_write >= fifo->item_sum) { fifo->ptr_write = fifo->ptr_write - fifo->item_sum + item_num - 1; } fifo->is_empty = false; if (fifo->ptr_write == fifo->ptr_read) { fifo->is_full = true; } return true; } /** * @brief fifo checks whether it can be read * @param fifo_index: fifo index * @return false: cannot be read. true: can be read */ bool fifo_readable(int fifo_index) { Fifo *fifo = (Fifo *)fifo_index; return !fifo->is_empty; } /** * @brief fifo read * @param fifo_index: fifo index * @param data: read data * @return false: failure.true: success */ bool fifo_read(int fifo_index, void *data) { Fifo *fifo = (Fifo *)fifo_index; if(fifo->is_empty) { return false; } memcpy(data, (char *)(fifo->fifo_ptr) + fifo->ptr_read * fifo->item_size, fifo->item_size); fifo->ptr_read + + ; if (fifo->ptr_read >= fifo->item_sum) { fifo->ptr_read = 0; } fifo->is_full = false; if (fifo->ptr_read == fifo->ptr_write) { fifo->is_empty = true; } return true; } /** * @brief fifo batch reading * @param fifo_index: fifo index * @param data: read data * @param item_num: the number of elements read * @return false: failure.true: success */ bool fifo_read_batch(int fifo_index, void *data, int item_num) { Fifo *fifo = (Fifo *)fifo_index; if (fifo_readable_item_count((int)fifo) < item_num) { return false; } memcpy(data, (char *)(fifo->fifo_ptr) + fifo->ptr_read * fifo->item_size, fifo->item_size * item_num); fifo->ptr_read + = item_num; if (fifo->ptr_read >= fifo->item_sum) { fifo->ptr_read = fifo->ptr_read - fifo->item_sum + item_num - 1; } fifo->is_full = false; if (fifo->ptr_read == fifo->ptr_write) { fifo->is_empty = true; } return true; } /** * @brief The number of elements readable by fifo * @param fifo_index: fifo index * @return number of elements */ int fifo_readable_item_count(int fifo_index) { Fifo *fifo = (Fifo *)fifo_index; if (fifo->ptr_write >= fifo->ptr_read) { return (fifo->ptr_write - fifo->ptr_read); } else { return (fifo->item_sum - fifo->ptr_read + fifo->ptr_write); } } /** * @brief The number of elements that fifo can write * @param fifo_index: fifo index * @return number of elements */ int fifo_writeable_item_count(int fifo_index) { Fifo *fifo = (Fifo *)fifo_index; if (fifo->ptr_write < fifo->ptr_read) { return (fifo->ptr_read - fifo->ptr_write); } else { return (fifo->item_sum - fifo->ptr_write + fifo->ptr_read); } }
The fifo.h file code is as follows:
#ifndef _FIFO_H_ #define _FIFO_H_ #include "stdlib.h" #include "stdio.h" #include "stdarg.h" #include "stdbool.h" #include "string.h" #include "math.h" extern int FifoAddr; /** * @brief Create fifo * @param item_sum: the number of elements in fifo. Note that it is not the number of bytes * @param item_size: element size. Unit: bytes * @return fifo index */ int fifo_create(int item_sum, int item_size); /** * @brief delete fifo * @param fifo_index: fifo index */ void fifo_delete(int fifo_index); /** * @brief fifo checks whether it can be written * @param fifo_index: fifo index * @retval false: cannot be written. true: can be written */ bool fifo_writeable(int fifo_index); /** * @brief fifo writing * @param fifo_index: fifo index * @param frame: write element pointer * @return false:failure.true:success */ bool fifo_write(int fifo_index, void *data); /** * @brief fifo batch writing * @param fifo_index: fifo index * @param data: write element pointer * @param @param item_num: the number of elements written * @return false:failure.true:success */ bool fifo_write_batch(int fifo_index, void *data, int item_num); /** * @brief fifo checks whether it can be read * @param fifo_index: fifo index * @return false: cannot be read. true: can be read */ bool fifo_readable(int fifo_index); /** * @brief fifo read * @param fifo_index: fifo index * @param data: read data * @return false: failure.true: success */ bool fifo_read(int fifo_index, void *data); /** * @brief fifo batch reading * @param fifo_index: fifo index * @param data: read data * @param item_num: the number of elements read * @return false: failure.true: success */ bool fifo_read_batch(int fifo_index, void *data, int item_num); /** * @brief The number of elements readable by fifo * @param fifo_index: fifo index * @return number of elements */ int fifo_readable_item_count(int fifo_index); /** * @brief The number of elements that fifo can write * @param fifo_index: fifo index * @return number of elements */ int fifo_writeable_item_count(int fifo_index); #endif