What is the behavior of io_fgets() on a non-blocking serial port?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

What is the behavior of io_fgets() on a non-blocking serial port?

Jump to solution
943 Views
razed11
Contributor V

Hi,

How will this function behave if the complete line (ending in \n) is not yet in the buffer?

Thanks,

Kenny

Tags (1)
0 Kudos
1 Solution
590 Views
matthewkendall
Contributor V

My understanding is that if there are no characters in the serial buffer then the underlying _io_serial_int_read returns zero (no characters read); this causes _io_fgetc to return IO_EOF; which causes _io_fgetline to return IO_EOF; which causes _io_fgets to return NULL. Nothing blocks.

If there are some characters in the serial buffer, but not a line-end character, then _io_fgetline gets a few characters from _io_fgetc before getting IO_EOF when the buffer runs out. At this point _io_fgetline returns IO_EOF, having populated the caller's buffer with the characters retrieved so far. _io_fgets then returns in the normal way. Again, nothing blocks.

In other words, the serial receive buffer becoming empty has much the same effect as receiving a line-end.

Edit: typo.

View solution in original post

0 Kudos
4 Replies
591 Views
matthewkendall
Contributor V

My understanding is that if there are no characters in the serial buffer then the underlying _io_serial_int_read returns zero (no characters read); this causes _io_fgetc to return IO_EOF; which causes _io_fgetline to return IO_EOF; which causes _io_fgets to return NULL. Nothing blocks.

If there are some characters in the serial buffer, but not a line-end character, then _io_fgetline gets a few characters from _io_fgetc before getting IO_EOF when the buffer runs out. At this point _io_fgetline returns IO_EOF, having populated the caller's buffer with the characters retrieved so far. _io_fgets then returns in the normal way. Again, nothing blocks.

In other words, the serial receive buffer becoming empty has much the same effect as receiving a line-end.

Edit: typo.

0 Kudos
590 Views
razed11
Contributor V

Thanks Matthew,

If IO_EOF is returned and fgets() returns NULL but characters are copied in to my buffer how do I know how many were copied? If I did then I could do multiple passes until I have a complete line. fgets() doesn't return the number copied.

Do you think I need to write my own line detection?

Kenny

0 Kudos
590 Views
matthewkendall
Contributor V
If IO_EOF is returned and fgets() returns NULL but characters are copied in to my buffer how do I know how many were copied?

In the second case (serial buffer has some characters but not a full line) _io_fgets returns in the normal way (i.e. it does return the number of characters read).

Do you think I need to write my own line detection?

If you really do want to always wait until there is a complete line available it is probably best to configure the port for blocking behaviour.

If you don't want to block (because the task must do other things) then the port must be configured for non-blocking access, which means you will have to stitch together the partial lines returned by fgets. However, you don't have a way to know where the line actually ends (because fgets strips the \n characters). So yes, I think you would need to use fgetc instead and do you own string assembly and line-end detection.

0 Kudos
590 Views
razed11
Contributor V

Thanks again,

The fgets() function doesn't seem to provide a way to know how many characters were read:

char * fgets ( char * str, int num, FILE * stream );

I'd prefer not to poll but I need that task free for other reasons. I suppose I can just go back to using read and just test if the last character of each chunk is \n which is what I expect.

Sometimes I wish these calls would peek at the buffer and copy only when the condition has been met. It would allow me to do some things more gracefully.

Kenny

0 Kudos