我无法解释为什么下面的代码大部分时间都可以工作,但每三次或第二次执行都会失败。
这是我的 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(),它是从单元测试内部调用的。