22254

Non blocking read with fixed data in input

Question:

I want use serial port to communicate with another device txdev, the problem is that txdev is sending data asynchronously and i don't want the read function to block, the good thing is that txdev is sending data with fixed size but i don't know how to use this trick. what i'am doing is the following :

fd = open(DEVICE_NAME, O_RDWR | O_NOCTTY); bzero(&termios_p, sizeof(termios_p)); termios_p.c_cflag = CS8|CSTOPB|CLOCAL|CREAD; termios_p.c_iflag = IGNPAR; termios_p.c_oflag = 0; termios_p.c_lflag = ~ICANON; termios_p.c_cc[VMIN]=DATA_LENGTH; termios_p.c_cc[VTIME]=10; cfsetispeed(&termios_p, BAUDRATE); cfsetospeed(&termios_p, BAUDRATE); tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&termios_p);

from <a href="https://stackoverflow.com/questions/18070731/linux-serial-port-blocking-read-with-timeout?lq=1" rel="nofollow">this post</a> i undrestand that this cause the read to be blocked VTIME = 0 is blocking as well.

Could anyone help me figure out the solution i think i have to use interrupt handler instead of a read do you agree ?

2nd question : Since a sender can't get synchronized with the receiver is there an interrupt handler that stores the received data on specified buffer (i undrestand that this is the case for Canonical mode but not in Non canonical mode) or this is only done when read function is reached, if i'am wrong please correct me

As usual thanks a lot.

Answer1:

<blockquote>

I want use serial port to communicate with another device txdev, the problem is that txdev is sending data asynchronously and i don't want the read function to block,

</blockquote>

You seem to misunderstand how a Linux application program should read from and write to a serial port. All data is buffered between your program and the UART. Your program does not have to be always ready to read the data as it comes off the wire. The OS (specifically the UART device driver and the tty subsystem which includes line disciplines) does that, and buffers the data for your program.

RS-232 is by definition an asynchronous communication link. The characters/bytes can be transmitted at any time. Message packets will arrive at any point in time, so the application program will have to wait for the bytes that comprise a message packet. That's a case for using blocking reads.

The typical problem of receiving serial data is how to perform a lexical scan of received data to identify a complete message packet. Text messages (canonical mode) simply use ASCII line control characters to delimit messages/lines. Even packets of fixed length need validation (to ensure that the message actually starts on the correct byte). See <a href="https://stackoverflow.com/questions/16177947/identification-of-packets-in-a-byte-stream/16180135#16180135" rel="nofollow">this example of scanning fixed-length packets</a>.

<blockquote>

i think i have to use interrupt handler instead of a read do you agree ?

</blockquote>

No, the UART device driver is already servicing its interrupts (or employing DMA) to capture every byte that is received off the serial link.

<blockquote>

Since a sender can't get synchronized with the receiver is there an interrupt handler that stores the received data on specified buffer (i undrestand that this is the case for Canonical mode but not in Non canonical mode) or this is only done when read function is reached,

</blockquote>

There is no need for the serial port on the receive end to "synchronize" with the sending serial port at the byte level. RS-232 is an asynchronous communication link: the sender can/will transmit a character/byte at any time, and the other end must be prepared to receive it (unless there is either hardware or software flowcontrol in place) at the device driver level (and not the application program).

The OS always buffers this received data. A <strong>read()</strong> syscall by an application program is merely a copy operation from the system buffer to the user buffer. This copy operation is for both canonical and non-canonical modes.

"Getting synchronized" is typically an issue to be resolved at the message or packet level by the protocol. Master-slave is a common configuration for defining a serial link protocol. The master side sends a query message to the slave side. The slave must always be prepared to receive a query. The slave side can respond with a transaction request or data capture or whatever, or a NAK message to indicate that it has nothing for the master. This request-response dialog is intended to control or pace the data flow (and processing load) between the two units.

<strong>Addendum</strong>

<blockquote>

what i'am planing to do is actually a blocking read (VTIME =0 VMIN = DATA_LENGTH) in an infinite loop

</blockquote>

Presumably you will always initiate your program before the sending device so that the first transmitted DATA_LENGTH will align with the first read by the program.

That will probably work most of the time in an ideal or monitored situation.<br /> But for industrial 24/7 applications, the possibility of losing message frame alignment is real (e.g. sending device is restarted in middle of a transmission), and therefore a scheme that has no active means to verify and regain message frame alignment is inadequate.

IOW a raw <strong>read()</strong> of the serial port may not return an aligned message in your buffer (i.e. buf[0] may not contain the first byte of the message).<br /> A much smaller VMIN with a nonzero VTIME is the typical termios configuration based on the premise that the serial link is idle (for a short interval) after each message.<br /> But the code should be robust to handle any/all message fragments as they are read. So more than one <strong>read()</strong> may be needed to reconstruct the entire message.

Recommend

  • Jquery Unobstrusive validation show errors manually for Valid
  • Spring MVC multiple url mapping to the same controller method
  • java Volatile/synchronization on arraylist
  • R regmatches() and stringr str_extract() dragging whitespaces along
  • Which PHP RPC (XML or JSON) library have you successfully used?
  • Spring integration warning Referenced bean 'org.springframework.scheduling.support.PeriodicTrig
  • Does ruby on rails have client side validation like ASP.NET MVC
  • Rewrite apply function to use recursion instead
  • How to redirect or show a page rather than “Forbidden” when i have directory listings off (htaccess/
  • LCD Programming with Arduino
  • How to make a user wait with Laravel
  • Where in the relevant specification is it documented that some comments in a SQL script are, in fact
  • Generating anchors with PyYAML.dump()?
  • Linking Ghostscript to pypdfocr in Windows Platform
  • Regex for Specific Tag
  • Get Currently Active User in Android
  • Portable JRE on Linux - possible?
  • Javascript/Jquery runs fast in desktop browsers, but slow in mobile/smartphone browsers…should I spl
  • How can we prepend rows to a react native list-view?
  • Memory error in python- how to use more memory
  • Differences in dis-assembled C code of GCC and Borland?
  • What's the purpose of QString?
  • Jackson Parser: ignore deserializing for type mismatch
  • Setting up SourceTree to merge unity3d scenes with UnityYAMLMerge
  • Algorithm for a smudge tool?
  • Email format validation in mvc3 view
  • C# - Is there a limit to the size of an httpWebRequest stream?
  • C# - Serializing and deserializing static member
  • How to add date and time under each post in guestbook in google app engine
  • Sending data from AppleScript to FileMaker records
  • Function pointer “assignment from incompatible pointer type” only when using vararg ellipsis
  • Apache 2.4 - remove | delete | uninstall
  • Cannot Parse HTML Data Using Android / JSOUP
  • How to include full .NET prerequisite for Wix Burn installer
  • How do you join a server to an Active Directory (domain)?
  • Understanding cpu registers
  • coudnt use logback because of log4j
  • Is it possible to post an object from jquery to bottle.py?
  • Checking variable from a different class in C#