0

我无法解释为什么下面的代码大部分时间都可以工作,但每三次或第二次执行都会失败。

这是我的 cunit 测试的一部分

assertTrue(io_register_output(consumer));
for(int i = 0; i < 2; ++i) {
    assertEquals(10, io_write("xxxxxxxxxx"));
}
io_flush();
printf("Result is: %s\n", result);

这是io_write

uint16_t io_write(char *data) {
    if (IOBuffer == NULL) return 0;
    uint16_t s = 0;

    while (*data != '\0') {
        IOBuffer->data[IOBuffer->write_position++] = *data;
        s += sizeof(*data);
        *data++;
        if (IOBuffer->write_position >= IO_BUFFER_SIZE){
            // buffer full, auto flush
            io_flush();
        }
    }
    return s;
}

我将 achar*写入缓冲区。如果我调用该函数一次,它每次都有效,但如果多次调用它,它有时会失败。我究竟做错了什么?

编辑:来自 io_buffer.h:

#ifndef IO_BUFFER_SIZE
#define IO_BUFFER_SIZE      512
#endif
#ifndef IO_MAX_CONSUMER
#define IO_MAX_CONSUMER     8
#endif

typedef struct consumer {
     uint16_t    read_position;
     void        (*fn)(char *);
} IOBuffer_consumer_t;

typedef struct IOBuffer_s {
     uint16_t    count_consumer;
     uint16_t    write_position;
     char        data[IO_BUFFER_SIZE];
     IOBuffer_consumer_t    consumer_arr[IO_MAX_CONSUMER]
} IOBuffer_t;

IOBuffer_t *IOBuffer;

来自 io_buffer.c 这是两个函数 io_write 和 io_flush:

uint16_t io_write(char *data){
    if(IOBuffer == NULL) return 0;
    uint16_t s = 0;

    while(*data != '\0') {
        IOBuffer->data[IOBuffer->write_position++] = *data;
        s += sizeof(*data);
        data++;
        if(IOBuffer->write_position >= IO_BUFFER_SIZE){
            // buffer full, auto flush
            io_flush();
        }
    }
    return s;
}

void io_flush(void){
    for(uint8_t i=0; i < IOBuffer->count_consumer; ++i){
        IOBuffer_consumer_t *cPtr = &IOBuffer->consumer_arr[i];
        char *data =  IOBuffer->data;
        // fast forward
        data = data + cPtr->read_position;
        char *send = calloc(IOBuffer->write_position - cPtr->read_position, sizeof(char));

        // concat charakters
        while(cPtr->read_position != IOBuffer->write_position ){
            sprintf(send, "%s%c", send, *data );
            ++cPtr->read_position;
            ++data;
        }
       cPtr->fn(send);
       cPtr->read_position = 0;
       free(send);
    }
    IOBuffer->write_position = 0;
}

目的是注册多个“消费者”以将输出发送到。它是目前在 Mac OS 上运行的一个 cu 单元测试,用于为 uCs 准备一些代码。根据配置,我想将输出发送到 uart、显示器,或者 - 在我的 mac 上的测试模式下 - 到测试例程,例如:

char *result;
void *consumer(char *in){
    sprintf(result, "%s", in);
    printf("consumer-1-get: %s\n", result);
}

来自我的单元测试。

同样,错误并非一直发生,但如果我将第二次或第三次写入 io_write,则经常发生错误。甚至 io_flush 也永远不会调用。

编辑 2:发现错误在某处是 io_flush(),它是从单元测试内部调用的。

4

0 回答 0