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

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

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

跳至解决方案
1,959 次查看
razed11
Contributor V

Hi,

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

Thanks,

Kenny

标记 (1)
0 项奖励
回复
1 解答
1,606 次查看
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 项奖励
回复
4 回复数
1,607 次查看
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 项奖励
回复
1,606 次查看
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 项奖励
回复
1,606 次查看
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 项奖励
回复
1,606 次查看
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 项奖励
回复