summaryrefslogtreecommitdiff
path: root/third_party/cherryrb/README.md
blob: df04502ca89a000d364192de4b3390f106c199b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# CherryRingBuffer

[中文版](./README_zh.md)

CherryRingBuffer is an efficient and easy-to-use ringbuffer that is based on the same principle as kfifo.

## Brief

### 1.Create and initialize a RingBuffer
```c
chry_ringbuffer_t rb;
uint8_t mempool[1024];

int main(void)
{
    /**
     * Note that the third parameter of the init function is 
     * the size of the memory pool (in bytes)
     * It is also the depth of the ringbuffer, 
     * which must be a power of 2 !!!
     * Example: 4, 16, 32, 64, 128, 1024, 8192, 65536, etc.
     */
    if(0==chry_ringbuffer_init(&rb, mempool, 1024)){
        printf("success\r\n");
    }else{
        printf("error\r\n");
    }

    return 0;
}
```

### 2.Lock-free use of the producer-consumer model
The read and write APIs, except for overwrite, do not require locking if they satisfy the requirement that the ringbuffer is read in only one thread and written in only one thread, because the read and write operations only operate on the read or write pointers separately.
```c
void thread_producer(void* param)
{
    char *data = "hello world";
    while(1){
        uint32_t len = chry_ringbuffer_write(&rb, data, 11);
        if(11 == len){
            printf("[P] write success\r\n");
        }else{
            printf("[P] write faild, only write %d byte\r\n", len);
        }
        vTaskDelay(100);
    }
}

void thread_consumer(void* param)
{
    char data[1024];
    while(1){
        uint32_t len =chry_ringbuffer_read(&rb, data, 11);
        if (len){
            printf("[C] read success, read %d byte\r\n",len);
            data[11]='\0';
            printf("%s\r\n",data);
        }else{
            printf("[C] read faild, no data in ringbuffer\r\n");
        }
        vTaskDelay(100);
    }
}
```

### 3. API Introduction

```c

    /**
     * Used to clear ringbuffer, while operating read and write pointers, 
     * multi-threaded need to add lock
     */
    chry_ringbuffer_reset(&rb);       

    /**
     * Used to clear ringbuffer, only operates on read pointers, 
     * called without locking in the only read thread
     */
    chry_ringbuffer_reset_read(&rb);

    /**
     * Get the total ringbuffer size (bytes)
     */
    uint32_t size = chry_ringbuffer_get_size(&rb);

    /**
     * Get ringbuffer used size (bytes)
     */
    uint32_t used = chry_ringbuffer_get_used(&rb);

    /**
     * Get ringbuffer free size (bytes)
     */
    uint32_t free = chry_ringbuffer_get_free(&rb);

    /**
     * Check if ringbuffer is full, full returns true
     */
    bool is_full = chry_ringbuffer_check_full(&rb);

    /**
     * Check if ringbuffer is empty, empty returns true
     */
    bool is_empty = chry_ringbuffer_check_empty(&rb);

    uint8_t data = 0x55;

    /**
     * Write a byte
     * No locking on the only write thread call
     * Success returns true, full returns false
     */
    chry_ringbuffer_write_byte(&rb, data);

    /**
     * overwriting write one byte, 
     * when ringbuffer is full will overwrite the earliest data
     * The non-full case is the same as chry_ringbuffer_write_byte
     * This API may operate on read and write pointers at the same time, 
     * so multiple threads need to add locks
     * Always return true
     */
    chry_ringbuffer_overwrite_byte(&rb, data);

    /**
     * Peek one byte from ringbuffer
     * The data is still retained in the ringbuffer
     * No locking on the only read thread call
     * Success returns true, empty returns false
     */
    chry_ringbuffer_peek_byte(&rb, &data);

    /**
     * Read one byte from ringbuffer
     * Data retrieval from ringbuffer
     * No locking on the only read thread call
     * Success returns true, empty returns false
     */
    chry_ringbuffer_read_byte(&rb, &data);

    /**
     * Drop one byte from ringbuffer
     * Data retrieval from ringbuffer
     * No locking on the only read thread call
     * Success returns true, empty returns false
     */
    chry_ringbuffer_drop_byte(&rb);

    /**
     * Write multi-byte, otherwise same as single byte write
     * Returns the actual length of the write
     */
    chry_ringbuffer_write(&rb, data, 1);

    /**
     * Overwrite multi-byte, otherwise same as single byte overwrite
     * Returns the actual length of the write
     */
    chry_ringbuffer_overwrite(&rb, data, 1);

    /**
     * Peek multiple bytes, otherwise same as single byte peek
     * Returns the length of the actual peek
     */
    chry_ringbuffer_peek(&rb, data, 1);

    /**
     * Read multiple bytes, otherwise same as single byte read
     * Returns the length of the actual read
     */
    chry_ringbuffer_read(&rb, data, 1);

    /**
     * Drop multiple bytes, otherwise same as single byte Drop
     * Returns the length of the actual drop
     */
    chry_ringbuffer_drop(&rb, 1);

    void *pdata;
    uint32_t size;

    /**
     * For dma start, get read memory address and max linear read size
     */
    pdata = chry_ringbuffer_linear_read_setup(&rb, &size);

    /**
     * For dma done, add read pointer
     * Returns the length of the actual add
     */
    size = chry_ringbuffer_linear_read_done(&rb, 512);

    /**
     * For dma start, get write memory address and max linear write size
     */
    pdata = chry_ringbuffer_linear_write_setup(&rb, &size);

    /**
     * For dma done, add write pointer
     * Returns the length of the actual add
     */
    size = chry_ringbuffer_linear_write_done(&rb, 512);

```