c - 如何制作内部带有 can_frame 结构的 FIFO 缓冲区?

标签 c linux can-bus

目前我正在做一个项目,其中有几个处理器在使用 CAN 总线之间进行通信。主 Controller (beagle bone)使用 can 总线控制其他设备。使用 socket can linux 框架,我编写了一个进程来读取从其他设备发送的 can 消息,现在我想将收到的消息放入 FIFO 缓冲区,然后将消息发送出去。 所以我需要写一个里面有can_frame结构的FIFO缓冲区。

例如:

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等),但我不知道如何解决这个问题。

如何制作一个可以在其中存储 can_frame 结构的 FIFO 缓冲区?

我需要用 C 语言来写

主要我打电话

can_buffer can_buff;

can_buff = new_can_buffer(100);

can_buffer_push(can_buff,frame);

frame = can_frame 我收到了

can_buff = fifo 缓冲区

最佳答案

嗯,您没有完全修改 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() 中也有错别字。

社论: 我强烈建议编写一个简单的测试程序来执行这些功能。这很令人沮丧,但会遇到一些这样的小陷阱。

关于c - 如何制作内部带有 can_frame 结构的 FIFO 缓冲区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40534619/

相关文章:

android - CAN总线与Android通讯咨询

当我重定向输出时,Python 程序不会在 docker 容器中的 shell 脚本中运行

can-bus - 是否可以模拟CAN总线仲裁?

c++ - 有没有办法找到一个dll暴露的所有功能

c - 使用 C 中的回溯算法求解数独

linux - docker 容器第一次执行完成后如何自定义其卷和端口?

linux - 减去ESP或RSP寄存器会产生哪个异常? (堆栈增长)

PHP 扩展 : Segmentation fault when returning from a function

c - 矩阵分配的段错误错误