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-------------- */
		}
	}
}

山和山不相遇,人与人要相逢