Ring buffer (环形数据采集区)
为了解决写SD过慢,从而采集数据不够快的问题
Ring buffer的定义,方法声明(放在头文件中)
/* ------------- ring buffer ---------------- */
#define BUFFER_SIZE 32768 // 环形缓冲区的大小
#define BUFFER_MASK (BUFFER_SIZE-1)
typedef struct {
uint8_t data[BUFFER_SIZE];
uint16_t head;
uint16_t tail;
} RingBuffer;
void buffer_init(RingBuffer *buffer);
int buffer_is_full(RingBuffer *buffer);
int buffer_is_empty(RingBuffer *buffer);
uint16_t buffer_read(RingBuffer *buffer, uint8_t *values, uint16_t length);
int buffer_write(RingBuffer *buffer, uint8_t *values, uint16_t length);
uint16_t buffer_get_data_available(RingBuffer *buffer);
/* ------------- circle buffer ---------------- */
Ring buffer的方法实现(放在源文件中)
/* ------------- ring buffer ---------------- */
void buffer_init(RingBuffer *buffer) {
buffer->head = 0;
buffer->tail = 0;
// buffer->count = 0;
}
int buffer_is_full(RingBuffer *buffer) {
return (((buffer->head + 1)&BUFFER_MASK) == buffer->tail);
}
int buffer_is_empty(RingBuffer *buffer) {
return (buffer->head == buffer->tail);
}
uint16_t buffer_get_data_available(RingBuffer *buffer) {
return (buffer->head - buffer->tail + BUFFER_SIZE) % BUFFER_SIZE;
}
int buffer_write(RingBuffer *buffer, uint8_t *values, uint16_t length) {
uint16_t space = (buffer->tail - buffer->head - 1 + BUFFER_SIZE) & BUFFER_MASK;
if (length > space) {
printf("buffer Full\r\n");// 缓冲区没有足够空间
return -1;
}
for (uint16_t i = 0; i < length; i++) {
buffer->data[buffer->head] = values[i];
buffer->head = (buffer->head + 1) % BUFFER_SIZE;
if (buffer->head >= BUFFER_SIZE) {
buffer->head = 0;
}
}
return 0;
}
uint16_t buffer_read(RingBuffer *buffer, uint8_t *values, uint16_t length) {
uint16_t data_available = (buffer->head - buffer->tail + BUFFER_SIZE) % BUFFER_SIZE;
if (data_available < length) {
printf("buffer insufficient\r\n");// 缓冲区数据不足
return 0;
}
for (uint16_t i = 0; i < length; i++) {
values[i] = buffer->data[buffer->tail];
buffer->tail = (buffer->tail + 1) % BUFFER_SIZE;
if (buffer->tail >= BUFFER_SIZE) {
buffer->tail = 0;
}
}
return length;
}
/* ------------- ring buffer ---------------- */
从buffer写入SD部分(放在main函数中)
void writeBuffer2SD(RingBuffer* p_imuBuffer, FIL* p_file){
if(g_recordTag){
// in recording, write 4096 bytes once to sd
if(g_recordTag&0x80){
UINT bw = 0;
uint8_t data_chunk[8192];
if (buffer_read(p_imuBuffer, data_chunk, 8192)) {
if (!(f_write(p_file, data_chunk, 8192, &bw))){
HAL_GPIO_WritePin(LED_STATUS_GPIO_Port, LED_STATUS_Pin, !HAL_GPIO_ReadPin(LED_STATUS_GPIO_Port, LED_STATUS_Pin));
}
else printf("Failed to write data.\n");
}
}
// after record, write remain data to sd
if(g_recordTag&0x01){
/* -----------write all data to sd-------------- */
uint16_t dataNum = buffer_get_data_available(p_imuBuffer);
UINT bw = 0;
if(dataNum != 0){
uint8_t data_chunk[dataNum];
buffer_read(p_imuBuffer, data_chunk, dataNum);
if (!(f_write(p_file, data_chunk, dataNum, &bw))){
HAL_GPIO_WritePin(LED_STATUS_GPIO_Port, LED_STATUS_Pin, !HAL_GPIO_ReadPin(LED_STATUS_GPIO_Port, LED_STATUS_Pin));
}
else printf("Failed to write data.\n");
}
f_close(p_file);
// while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER);
buffer_init(p_imuBuffer);
g_recordTag = 0; //clear the tag
/* -----------write all data to sd-------------- */
}
}
}