环形缓冲区
最近需要重写处理串口不定长数据,期望实现一种通用的方法,以便日后处理诸如网口之类的数据包。为了一次性解决不完整包,粘包等特殊数据包,想到了这种方法。
思路就是将所有接受到的数据放入环形缓冲区,那么应用程序就可慢一点过来取数据再处理。
关于环形缓冲区的介绍很多,这里不做详细介绍。这些蛮好的:https://github.com/AndersKaloer/Ring-Buffer/tree/master
#include <stdio.h> #include "ring_buffer.h" #include <stdlib.h> int main(void) { ring_buffer_t rb ; rb.buffer_ptr = (unsigned char*)malloc(sizeof(char) * 8); Ring_Buffer_Init(&rb, (unsigned char*)malloc(sizeof(char) * 8), 8); Ring_Buffer_Write(&rb, 5); Ring_Buffer_Write(&rb, 6); Ring_Buffer_Write(&rb, 7); Ring_Buffer_Write(&rb, 8); Ring_Buffer_Write(&rb, 9); printf("length: %d\n",Ring_Buffer_Length(&rb)); Ring_Buffer_Print(&rb); printf("Hello World\n"); return 0; }
1 /* 2 @file:ring_buffer.h 3 @brief:实现ringbuffer,缓冲区写满了不可覆盖写入,最大长度是size-1 4 @author:许言 5 @date:2024-02-26 6 */ 7 #ifndef _RING_BUFFER_H_ 8 #define _RING_BUFFER_H_ 9 10 typedef struct _ring_buffer_t 11 { 12 volatile unsigned int read_index; 13 volatile unsigned int write_index; 14 unsigned int buffer_size; 15 unsigned char* buffer_ptr; 16 }ring_buffer_t,*p_ring_buffer_t; 17 18 19 20 /* 21 @brief:初始化ringbuffer 22 @para:无 23 @return:无 24 25 */ 26 void Ring_Buffer_Init(ring_buffer_t *ring_buffer,unsigned char* pool, unsigned int size); 27 28 /* 29 @brief:初始化ringbuffer 30 @para:无 31 @return:无 32 33 */ 34 unsigned int Ring_Buffer_Length(ring_buffer_t *ring_buffer); 35 36 /* 37 @brief:向缓冲区写一个字节,这里的策略是如果缓冲区满了,就不让写了 38 @para:ringbuffer句柄 39 @para:ch:需要保存字符 40 @return:失败返回-1 41 42 */ 43 int Ring_Buffer_Write(ring_buffer_t* ring_buffer, unsigned char ch); 44 /* 45 @brief:从缓冲区读一个字节 46 @para:ringbuffer句柄 47 @para:ch:指向读取字符的地址 48 @return:失败返回-1 49 50 */ 51 int Ring_Buffer_Read(ring_buffer_t* ring_buffer, unsigned char *ch); 52 /* 53 @brief:打印缓冲区的所有值 54 @para:ringbuffer句柄 55 @return:无 56 57 */ 58 void Ring_Buffer_Print(ring_buffer_t* ring_buffer); 59 60 #endif
1 /* 2 @file:ring_buffer.c 3 @brief:实现ringbuffer,缓冲区写满了不可覆盖写入,最大长度是size-1 4 @author:许言 5 @date:2024-02-26 6 */ 7 #include "ring_buffer.h" 8 #include <stdio.h> 9 #include <stdlib.h> 10 11 /* 12 @brief:初始化ringbuffer 13 @para:无 14 @return:无 15 16 */ 17 void Ring_Buffer_Init(ring_buffer_t *ring_buffer,unsigned char* pool, unsigned int size) 18 { 19 ring_buffer->buffer_ptr = pool; 20 ring_buffer->read_index = 0; 21 ring_buffer->write_index = 0; 22 ring_buffer->buffer_size = size; 23 } 24 25 /* 26 @brief:初始化ringbuffer 27 @para:无 28 @return:无 29 30 */ 31 unsigned int Ring_Buffer_Length(ring_buffer_t *ring_buffer) 32 { 33 return ring_buffer->write_index - ring_buffer->read_index; 34 } 35 36 37 /* 38 @brief:向缓冲区写一个字节 39 @para:ringbuffer句柄 40 @para:ch:需要保存字符 41 @return:失败返回-1 42 43 */ 44 int Ring_Buffer_Write(ring_buffer_t* ring_buffer, unsigned char ch) 45 { 46 /*如果缓冲区满就返回失败*/ 47 if(ring_buffer->read_index == ((ring_buffer->write_index + 1 )%ring_buffer->buffer_size) ) 48 return -1; 49 50 ring_buffer->buffer_ptr[ring_buffer->write_index] = ch; 51 ring_buffer->write_index = (ring_buffer->write_index + 1)%ring_buffer->buffer_size; 52 53 return 0; 54 } 55 56 /* 57 @brief:从缓冲区读一个字节 58 @para:ringbuffer句柄 59 @para:ch:指向读取字符的地址 60 @return:失败返回-1 61 62 */ 63 int Ring_Buffer_Read(ring_buffer_t* ring_buffer, unsigned char *ch) 64 { 65 /*如果缓冲区空就读不了,返回失败*/ 66 if(ring_buffer->read_index == ring_buffer->write_index) 67 return -1; 68 69 *ch = ring_buffer->buffer_ptr[ring_buffer->read_index]; 70 ring_buffer->read_index = (ring_buffer->read_index + 1)%ring_buffer->buffer_size; 71 return 0; 72 } 73 74 /* 75 @brief:打印缓冲区的所有值 76 @para:ringbuffer句柄 77 @return:无 78 79 */ 80 void Ring_Buffer_Print(ring_buffer_t* ring_buffer) 81 { 82 /*如果缓冲区空就读不了,返回失败*/ 83 unsigned int r_index = ring_buffer->read_index; 84 unsigned int w_index = ring_buffer->write_index; 85 86 printf("ringbuffer: "); 87 while( w_index != r_index) 88 { 89 printf("0x%.2x ",ring_buffer->buffer_ptr[r_index]); 90 r_index = (r_index + 1)%ring_buffer->buffer_size; 91 } 92 printf("\n"); 93 }