C语言 如何使用can_frame结构内部的FIFO缓冲区



目前我正在研究一个项目,其中几个处理器使用can总线进行通信。主控制器(小猎犬骨)使用can总线控制其他设备。使用套接字linux框架,我写了一个进程,读取从其他设备发送的can消息,现在我想把我得到的消息放入FIFO缓冲区,然后对消息进行obbrabotam。所以我需要写FIFO buffer与can_frame结构里面。

例如:

struct can_buffer {
    struct can_frame *frames;
    int head;
    int tail;
    int size;
};
can_buffer new_can_buffer (size_t capacity)
{
    can_buffer rb = malloc(sizeof(struct can_buffer));
    if (rb) {
        /* One byte is used for detecting the full condition. */
        rb->size = capacity + 1;
        rb->frames = malloc(rb->size * sizeof(struct can_frame));
        if (rb->frames)
            can_buffer_reset(rb);
        else {
            free(rb);
            return 0;
        }
    }
    return rb;
}
size_t can_buffer_size(const struct can_buffer *rb)
{
    return rb->size;
}
size_t can_buffer_capacity(const struct can_buffer *rb)
{
    return can_buffer_buffer_size(rb) - 1;
}
size_t can_buffer_free(const struct can_buffer *rb)
{
    if (rb->head >= rb->tail)
        return can_buffer_capacity(rb) - (rb->head - rb->tail);
    else
        return rb->tail - rb->head - 1;
}
int can_buffer_is_full(const struct can_buffer *rb)
{
    return can_buffer_free(rb) == 0;
}
int can_buffer_is_empty(const struct can_buffer *rb)
{
    return can_buffer_free(rb) ==can_buffer_capacity(rb);
}
void can_buffer_reset(can_buffer rb)
{
    rb->head = rb->tail = 0;
}

.................

/*将消息添加到队列末尾。*/

void can_buffer_push(struct can_buffer *cb, struct can_frame *frame)
{
    memcpy(&cb->frames[cb->tail], frame, sizeof(struct can_frame));
    cb->tail = (cb->tail + 1) % cb->size;
}
/* Retrieve message from the start of the queue. */
can_frame *can_buffer_pop(struct can_buffer *cb)
{
    struct can_frame *frame;
    memcpy(frame, &cb->frames[cb->head], sizeof(struct can_frame));
    cb->head = (cb->head + 1) % cb->size;
    return frame;
}

但是我做不到。我认为问题是,每个can_frame结构内部是一个结构,这是问题(例如int, char等),但我不知道如何解决这个问题。

我怎么能做一个FIFO缓冲区,可以存储can_frame结构里面?

我需要用C语言写这个

in main I call

can_buffer can_buff;
can_buff = new_can_buffer(100);
can_buffer_push(can_buff,frame);

frame = can_frame

can_buff = fifo buffer

嗯,您没有完全修改ringbuf例程。具体来说,您没有为这里的结构分配足够的空间:

if (rb) {
    /* One byte is used for detecting the full condition. */
    rb->size = capacity + 1;
    rb->frames = malloc(rb->size);
    if (rb->frames)
        ringbuf_reset(rb);
    else {
        free(rb);
        return 0;
    }
}

malloc需要

rb->frames = malloc(rb->size * sizeof(struct can_frame));

你应该在下一行更新ringbuf_reset()调用到你重命名的can_buffer_reset()


附录:

我刚刚注意到您还需要将ringbuf_reset()函数更新为rb->head = rb->tail = 0


附录2:

引用新添加的代码,can_buffer_pop()将不能正常工作,因为它不检查消息是否存在,也不为弹出的消息分配内存。

can_buffer_capacity()也有一个错别字。

编辑:我强烈建议编写一个简单的测试程序来执行这些函数。这是令人沮丧的,但会抓住一些这样的小陷阱。

最新更新