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,956件の閲覧回数
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,603件の閲覧回数
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,604件の閲覧回数
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,603件の閲覧回数
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,603件の閲覧回数
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,603件の閲覧回数
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 件の賞賛
返信