环形缓冲区

最近需要重写处理串口不定长数据,期望实现一种通用的方法,以便日后处理诸如网口之类的数据包。为了一次性解决不完整包,粘包等特殊数据包,想到了这种方法。

思路就是将所有接受到的数据放入环形缓冲区,那么应用程序就可慢一点过来取数据再处理。

关于环形缓冲区的介绍很多,这里不做详细介绍。这些蛮好的: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;
}
main.c
 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
ring_buffer.h
 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 }
ring_buffer.c
posted @ 2024-02-26 20:31  njit-sam  阅读(20)  评论(0编辑  收藏  举报