Register RS232 on Linux without waiting for a new line

I tried to write data from RS232 to a file with cat:

cat /dev/ttyS0 > rs232.log 

As a result, I had everything in my file except the last line.

By printing to stdout, I was able to find that the cat only writes the output if it receives a newline ('\ n'). I found the same thing:

 dd bs=1 if=/dev/ttyS0 of=rs232.log 

After reading, How can I print text right away without waiting for a new line in Perl? I was starting to think if this could be a buffering problem with either the Linux Kernel or the coreutils package.

According to TJD's comment, I wrote my own C program, but still had the same problems:

 #include <stdio.h> #include <stdlib.h> int main(int argc, char* args[]) { char buffer; FILE* serial; serial = fopen(args[1],"r"); while(1) { buffer = fgetc(serial); printf("%c",buffer); } } 

Based on the results of my own C code, this seems like a problem with Linux-Kernel.

+4
source share
2 answers

You open TTY. When this TTY is in cookie (aka canonical) mode, it performs line processing (for example, backspace removes the previous character from the buffer). You want to put TTY in raw mode to receive every byte when it arrives, and not wait for the end of the line.

From the man page :

Canonical and noncanonical mode

Setting the canon ICANON flag in c_lflag determines whether the terminal will operate in canonical mode (ICANON set) or non-canonical mode (ICANON unset). The default is ICANON.

In canonical mode:

  • Entrance is done in turn. An input line is available when one line of delimiters (NL, EOL, EOL2 or EOF at the beginning of the line). Except in the case of EOF, a line delimiter is included in the buffer returned by read (2).

  • Line editing is enabled (ERASE, KILL; and if the IEXTEN flag is set: WERASE, REPRINT, LNEXT). Reading (2) returns no more than one line of input; if read (2) requested fewer bytes than is available in the current input line, then only as many bytes as requested are read, and the remaining characters will be available for future reading (2).

In non-canonical mode, input is available immediately (without the user having to enter a line separator character) and line editing is disabled.

The simplest thing is to just call cfmakeraw .

+5
source

It works?

 perl -e 'open(IN, "/dev/ttyS0") || die; while (sysread(IN, $c, 1)) { print "$c" }' 

This job:

 $ echo -n ccc|perl -e 'while (sysread(STDIN, $c, 1)) { print "$c" } ' ccc$ 
0
source

Source: https://habr.com/ru/post/1437588/


All Articles