A data structure that uses a single, fixed-size buffer as if it were connected end-to-end (circular). More...
Data Structures | |
| struct | ring_buffer_t |
| Ring buffer structure. More... | |
Functions | |
| void | ring_buffer_init (ring_buffer_t *ring_buffer, u8_t *buffer, size_t buffer_size) |
| Initialize the ring buffer. | |
| bool_t | ring_buffer_empty (ring_buffer_t *ring_buffer) |
| See if the ring buffer is empty. | |
| bool_t | ring_buffer_full (ring_buffer_t *ring_buffer) |
| See if the ring buffer is full. | |
| bool_t | ring_buffer_write_byte (ring_buffer_t *ring_buffer, const u8_t data) |
| Write (store) a byte in the ring buffer. | |
| u16_t | ring_buffer_write_data (ring_buffer_t *ring_buffer, const u8_t *data, u16_t bytes_to_write) |
| Write (store) data in the ring buffer. | |
| bool_t | ring_buffer_read_byte (ring_buffer_t *ring_buffer, u8_t *data) |
| Read (retrieve) a byte from the ring buffer. | |
| u16_t | ring_buffer_read_data (ring_buffer_t *ring_buffer, u8_t *data, u16_t bytes_to_read) |
| Read (retrieve) data from the ring buffer. | |
Files: ring_buffer.h & ring_buffer.c
A fixed-sized buffer is managed as a FIFO buffer with a "zero-copy" policy, i.e. data is not shifted (copied) when data is removed or added to the buffer. If more data is written to the buffer than there is space for, it is ignored/discarded; no buffer overflow vulnerability.
In this implementation, the maximum amount of bytes that can be stored is one less than the size of the fixed-size buffer, e.g. if the buffer size is 8 bytes, then a maximum of 7 bytes can be stored.
Graphical examples:
Buffer is empty:
start head end
| | |
[ ][ ][ ][ ][ ][ ][ ][ ]
|
tail
One byte is written to the buffer ('1'):
head
|
[ ][ ][ ][ ][1][ ][ ][ ]
|
tail
One byte is read ('1'); buffer is empty again:
head
|
[ ][ ][ ][ ][ ][ ][ ][ ]
|
tail
5 bytes are written ('2','3','4','5','6'); buffer wraps:
head
|
[5][6][ ][ ][ ][2][3][4]
|
tail
2 bytes are written ('7','8'); buffer is full:
head
|
[5][6][7][8][ ][2][3][4]
|
tail
| void ring_buffer_init | ( | ring_buffer_t * | ring_buffer, | |
| u8_t * | buffer, | |||
| size_t | buffer_size | |||
| ) |
| ring_buffer | Pointer to the ring buffer object | |
| buffer | Fixed-size data buffer | |
| buffer_size | Fixed-size data buffer size |
Definition at line 58 of file ring_buffer.c.
References ring_buffer_t::end, ring_buffer_t::head, ring_buffer_t::start, and ring_buffer_t::tail.
Referenced by uart1_init(), uart2_init(), usart0_init(), and usart1_init().
| bool_t ring_buffer_empty | ( | ring_buffer_t * | ring_buffer | ) |
| ring_buffer | Pointer to the ring buffer object |
| TRUE | buffer is empty | |
| FALSE | buffer contains data |
Definition at line 69 of file ring_buffer.c.
References ring_buffer_t::head, and ring_buffer_t::tail.
Referenced by uart1_rx_buffer_empty(), uart1_tx_buffer_empty(), uart1_tx_finished(), uart2_rx_buffer_empty(), uart2_tx_buffer_empty(), uart2_tx_finished(), usart0_rx_buffer_empty(), usart0_tx_buffer_empty(), usart0_tx_finished(), usart1_rx_buffer_empty(), usart1_tx_buffer_empty(), and usart1_tx_finished().
| bool_t ring_buffer_full | ( | ring_buffer_t * | ring_buffer | ) |
| ring_buffer | Pointer to the ring buffer object |
| TRUE | buffer is full | |
| FALSE | buffer is NOT full |
Definition at line 74 of file ring_buffer.c.
References ring_buffer_t::end, ring_buffer_t::head, ring_buffer_t::start, and ring_buffer_t::tail.
Referenced by uart1_tx_buffer_full(), uart2_tx_buffer_full(), usart0_tx_buffer_full(), and usart1_tx_buffer_full().
00075 { 00076 // Calculate next position of in pointer 00077 u8_t *next_pos = ring_buffer->head; 00078 if (next_pos == ring_buffer->end) 00079 { 00080 // Wrap pointer to start of buffer 00081 next_pos = ring_buffer->start; 00082 } 00083 else 00084 { 00085 // Increment pointer 00086 next_pos++; 00087 } 00088 00089 return(next_pos == ring_buffer->tail); 00090 }
| bool_t ring_buffer_write_byte | ( | ring_buffer_t * | ring_buffer, | |
| const u8_t | data | |||
| ) |
| ring_buffer | Pointer to the ring buffer object | |
| data | The byte to store in the ring buffer |
| TRUE | Byte has been stored in the ring buffer | |
| FALSE | Buffer is full and byte was not stored |
Definition at line 92 of file ring_buffer.c.
References ring_buffer_t::end, ring_buffer_t::head, ring_buffer_t::start, and ring_buffer_t::tail.
Referenced by uart1_tx_byte(), uart2_tx_byte(), usart0_tx_byte(), and usart1_tx_byte().
00094 { 00095 // Calculate next position of in pointer 00096 u8_t *next_pos = ring_buffer->head; 00097 if (next_pos == ring_buffer->end) 00098 { 00099 // Wrap pointer to start of buffer 00100 next_pos = ring_buffer->start; 00101 } 00102 else 00103 { 00104 // Increment pointer 00105 next_pos++; 00106 } 00107 00108 // Make sure buffer is not full 00109 if (next_pos == ring_buffer->tail) 00110 { 00111 // Buffer is full 00112 return FALSE; 00113 } 00114 00115 // Add data to buffer 00116 *ring_buffer->head = data; 00117 00118 // Advance pointer 00119 ring_buffer->head = next_pos; 00120 00121 return TRUE; 00122 }
| u16_t ring_buffer_write_data | ( | ring_buffer_t * | ring_buffer, | |
| const u8_t * | data, | |||
| u16_t | bytes_to_write | |||
| ) |
| ring_buffer | Pointer to the ring buffer object | |
| data | Pointer to array of data to be stored in the ring buffer | |
| bytes_to_write | Amount of data bytes to be written |
Definition at line 124 of file ring_buffer.c.
References ring_buffer_t::end, ring_buffer_t::head, ring_buffer_t::start, and ring_buffer_t::tail.
Referenced by uart1_tx_data(), uart2_tx_data(), usart0_tx_data(), and usart1_tx_data().
00127 { 00128 u8_t *next_pos; 00129 u16_t bytes_written = 0; 00130 00131 while (bytes_to_write) 00132 { 00133 // Calculate next position of in pointer 00134 next_pos = ring_buffer->head; 00135 if (next_pos == ring_buffer->end) 00136 { 00137 // Wrap pointer to start of buffer 00138 next_pos = ring_buffer->start; 00139 } 00140 else 00141 { 00142 // Increment pointer 00143 next_pos++; 00144 } 00145 // Make sure buffer is not full 00146 if (next_pos == ring_buffer->tail) 00147 { 00148 // Buffer is full 00149 break; 00150 } 00151 00152 // Add data to buffer 00153 *ring_buffer->head = *data++; 00154 00155 // Advance pointer 00156 ring_buffer->head = next_pos; 00157 00158 // Next byte 00159 bytes_written++; 00160 bytes_to_write--; 00161 } 00162 00163 return bytes_written; 00164 }
| bool_t ring_buffer_read_byte | ( | ring_buffer_t * | ring_buffer, | |
| u8_t * | data | |||
| ) |
| ring_buffer | Pointer to the ring buffer object | |
| data | Pointer to location where byte must be stored |
| TRUE | Valid byte has been retrieved | |
| FALSE | Buffer is empty |
Definition at line 166 of file ring_buffer.c.
References ring_buffer_t::end, ring_buffer_t::head, ring_buffer_t::start, and ring_buffer_t::tail.
Referenced by uart1_get_rx_byte(), uart2_get_rx_byte(), usart0_get_rx_byte(), and usart1_get_rx_byte().
00168 { 00169 u8_t *next_pos; 00170 00171 // See if there is data in the buffer 00172 if (ring_buffer->head == ring_buffer->tail) 00173 { 00174 // Buffer is empty 00175 return FALSE; 00176 } 00177 00178 // Fetch data 00179 *data = *ring_buffer->tail; 00180 00181 // Calculate next position of out pointer 00182 next_pos = ring_buffer->tail; 00183 if (next_pos == ring_buffer->end) 00184 { 00185 // Wrap pointer to start of buffer 00186 next_pos = ring_buffer->start; 00187 } 00188 else 00189 { 00190 // Increment pointer 00191 next_pos++; 00192 } 00193 00194 // Advance pointer 00195 ring_buffer->tail = next_pos; 00196 00197 return TRUE; 00198 }
| u16_t ring_buffer_read_data | ( | ring_buffer_t * | ring_buffer, | |
| u8_t * | data, | |||
| u16_t | bytes_to_read | |||
| ) |
| ring_buffer | Pointer to the ring buffer object | |
| data | Pointer to location where data must be stored | |
| bytes_to_read | Number of bytes to retrieve |
Definition at line 200 of file ring_buffer.c.
References ring_buffer_t::end, ring_buffer_t::head, ring_buffer_t::start, and ring_buffer_t::tail.
Referenced by uart1_get_rx_data(), uart2_get_rx_data(), usart0_get_rx_data(), and usart1_get_rx_data().
00203 { 00204 u8_t *next_pos; 00205 u16_t bytes_read = 0; 00206 00207 while (bytes_to_read) 00208 { 00209 // See if there is data in the buffer 00210 if (ring_buffer->head == ring_buffer->tail) 00211 { 00212 // Buffer is empty 00213 break; 00214 } 00215 // Fetch data 00216 *data++ = *ring_buffer->tail; 00217 00218 // Calculate next position 00219 next_pos = ring_buffer->tail; 00220 if (next_pos == ring_buffer->end) 00221 { 00222 // Wrap pointer to start of buffer 00223 next_pos = ring_buffer->start; 00224 } 00225 else 00226 { 00227 // Increment pointer 00228 next_pos++; 00229 } 00230 00231 // Advance pointer 00232 ring_buffer->tail = next_pos; 00233 00234 // Next byte 00235 bytes_read++; 00236 bytes_to_read--; 00237 } 00238 00239 return bytes_read; 00240 }
1.6.3