【发布时间】:2018-08-16 10:56:59
【问题描述】:
我需要一个环形缓冲区(C 语言),它可以在运行时保存任何类型的对象(几乎数据将是不同的信号值,如电流(100 毫秒和 10 毫秒)和温度等)(我我不确定它是否必须是固定大小)并且它需要非常高性能。尽管它处于多任务嵌入式环境中。
实际上我需要这个缓冲区作为备份,这意味着嵌入式软件将正常工作并将数据保存到环形缓冲区中,到目前为止,无论出于何种原因,当发生错误时,我可以参考测量值然后我将能够查看它们并确定问题。另外我需要在环形缓冲区上做一个时间戳,这意味着存储在环形缓冲区上的每个数据(信号值)都将与测量的时间一起存储。
任何代码或想法将不胜感激。一些需要的操作是:
创建一个特定大小的环形缓冲区。 将其与整个软件链接。 放在尾部。 从头上得到。 出错时,读取数据及其发生时间(时间戳)。 返回计数。 缓冲区满时覆盖。
#include<stdint.h>
#include<stdio.h>
#include<stdlib.h>
typedef struct ring_buffer
{
void * buffer; // data buffer
void * buffer_end; // end of data buffer
void * data_start; // pointer to head
void * data_end; // pointer to tail
uint64_t capacity; // maximum number of items in buffer
uint64_t count; // number of items in the buffer
uint64_t size; // size of each item in the buffer
} ring_buffer;
void rb_init (ring_buffer *rb, uint64_t size, uint64_t capacity )
{
rb->buffer = malloc(capacity * size);
if(rb->buffer == NULL)
// handle error
rb->buffer_end = (char *)rb->buffer + capacity * size;
rb->capacity = capacity;
rb->count = 0;
rb->size = size;
rb->data_start = rb->buffer;
rb->data_end = rb->buffer;
}
void cb_free(ring_buffer *rb)
{
free(rb->buffer);
// clear out other fields too, just to be safe
}
void rb_push_back(ring_buffer *rb, const void *item)
{
if(rb->count == rb->capacity){
// handle error
}
memcpy(rb->data_start, item, rb->size);
rb->data_start = (char*)rb->data_start + rb->size;
if(rb->data_start == rb->buffer_end)
rb->data_start = rb->buffer;
rb->count++;
}
void rb_pop_front(ring_buffer *rb, void *item)
{
if(rb->count == 0){
// handle error
}
memcpy(item, rb->data_end, rb->size);
rb->data_end = (char*)rb->data_end + rb->size;
if(rb->data_end == rb->buffer_end)
rb->data_end = rb->buffer;
rb->count--;
}
【问题讨论】:
-
"current (100ms and 10ms)" 这是什么意思?
-
这意味着,例如,在运行时将读取两个不同的电流信号,一个每 10 毫秒读取一次,另一个在 100 毫秒读取一次
-
@AlexF 在资源受限的嵌入式系统中制作泛型类型的硬拷贝是个坏主意,不要那样做。它会使程序膨胀很多。
-
@AlexF 为什么在这样的系统上你甚至会有多种类型,以至于你需要实现通用 ADT?早在我看到一行代码之前,这就是主要的代码气味。
-
@Lundin 程序太长了,没错
标签: c