带时间戳的环形缓冲区

时间:2018-08-16 10:56:59

标签: c

我需要一个环形缓冲区(用C语言编写),该缓冲区可以在运行时保存任何类型的对象(几乎数据将是不同的信号值,例如电流(100ms和10ms)和温度等)(我不确定它是否必须是固定大小),并且需要非常高的性能。尽管它是在多任务嵌入式环境中。

实际上,我需要此缓冲区作为备份,这意味着嵌入式软件将正常运行并将数据保存到环形缓冲区中,到目前为止,无论出于何种原因,当发生错误时,我都可以参考测量值,然后我就可以看一下并确定问题所在。另外,我需要在环形缓冲区上做一个时间戳记,这意味着存储在环形缓冲区上的每个数据(信号值)都将与测量时间一起存储。

任何代码或想法都将不胜感激。所需的一些操作是:

创建具有特定大小的环形缓冲区。 将其与整个软件链接。 放在尾巴。 从头上得到。 错误时,读取数据及其发生的时间(时间戳)。 返回计数。 当缓冲区已满时覆盖。

#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--;
 }

1 个答案:

答案 0 :(得分:0)

使用通用类型的硬拷贝创建环形缓冲区/ FIFO对于嵌入式系统而言是非常成问题的设计。如此接近硬件的代码,不需要高级别的抽象。

要么用数据类型标记(如枚举)加void*的环形缓冲区来分配分配给其他位置的数据,要么制作所有数据都属于同一类型的环形缓冲区。其他所有内容很可能是混淆的程序设计(“ XY问题”)。

您需要一些方法来在内部锁定对环形缓冲区的访问,以使其成为线程安全/中断安全的。这以及时间戳,必须由环形缓冲区ADT在内部进行处理。