AndreRenaud/simple_uart

simple_uart_has_data: Inconsistency between README.md and simple_uart.h

Closed this issue · 9 comments

andkae commented

Hi André,

i found an discrepancy between the c file:

* Returns how many data bytes available on the uart

and the README:

Determine if there is outstanding data available to read

If i try to poll in a while loop, i end up in an infinite loop:

16/3 Len/Avail

The Return seems to be three but i expect 16 bytes.

How is this function intended to be used?

Thanks for your support!

BR,
Andreas

It should probably be changed to match the header file, not the docs. It's returning a count of characters that could be read.

I'm not sure what you mean about the loop - can you paste the code? If you're not reading the data, then it will just loop forever. Are you sending it 16 bytes of data, and only seeing 3?

andkae commented

It's returning a count of characters that could be read.

Okay. Perfect.

This is my code:

static uint32_t my_uart_read( my_type *self, void* data, uint32_t len )
{
    /** Variables **/
    uint32_t    r = 0;              // number of recieved bytes

    /* Function Call Message */
    if ( 0 != self->uint8MsgLevel ) { printf("__FUNCTION__ = %s\n", __FUNCTION__); };
    /* wait until expected number of data bytes are available */
    while ( len != ((uint32_t) simple_uart_has_data(self->uart)) ) {
        printf("%i/%i Len/Avail\n", len, simple_uart_has_data(self->uart));
        usleep(1000);
    }
    /* UART Read */
    r = (uint32_t) simple_uart_read(self->uart, data, (int) len);
    /* function finish */
    return r;
}

I like to wait in a loop until i have all requested bytes in the buffer. In My Example i expect 16 Byte the function has_data shows only 3 bytes. If i read the data i'll have 16byte data.

Thanks for your help.

BR,
Andreas

andkae commented

Are you sending it 16 bytes of data, and only seeing 3?

I send 3 Byte data and expect 16 byte

I'm unclear on how the buffering works on Windows, but you may have to drain some of the data to get it to funnel through. Can you try this instead (untested):

static uint32_t my_uart_read( my_type *self, void* data, uint32_t len )
{
    /** Variables **/
    uint32_t    r = 0;              // number of recieved bytes
    uint8_t *d8 = data;

    /* Function Call Message */
    if ( 0 != self->uint8MsgLevel ) { printf("__FUNCTION__ = %s\n", __FUNCTION__); };
    /* wait until expected number of data bytes are available */
    while (r < len) {
        int this_read = simple_uart_read(self->uart, &d8[r], len - r);
        printf("read %d of %d - %d remaining\n", this_read, len, len - r);
        if (this_read < 0) {
           // error
           // if it's a timeout error, we may want to continue;
           return this_read;
        }
        r += this_read;
        usleep(1000);
    }
    /* function finish */
    return len;
}
andkae commented

The topic with the count was my fault, after changing to waiting for bytes i missed to adjust the number of required bytes accordingly.

This works very fine for me

	/* read until number of required bytes are captured */
	while ( r < len ) {
		r = r + ((uint32_t) simple_uart_read(self->uart, data+r, (int) (len-r)));
	}

If you like i can make an PR for the README.md change

That would be great. Thanks.

I appreciate all the effort you're putting in to this.

You do want to check that you abort if you see a negative return value from simple_uart_read though - that would indicate some kind of error (like a close com port, or a device failure such as removing a USB serial dongle from the PC etc...)

andkae commented

oh, good hint, thanks

akaeba commented

Done in #19