Thread: Reading from serial device

  1. #1
    Registered User
    Join Date
    Aug 2008
    Posts
    26

    Reading from serial device

    Hello,

    I am trying to read from a device that spits out 2 values simultaneously per line when i read from the device through cat /dev/device. These readings are split up by a comma.

    Example:
    249, 371

    165, 398
    etc ...

    I am programming on a Linux machine and using the read() function. I have never done any serial programming. Is there a flag I can use in the read() function to read until a newline delimiter or the like. If I am on the computer and use the cat command it spits it out perfect, but when I read from the code it only outputs in proper format when I use 1 for the count parameter. I tried multiple values and none of them would give me an output like the examples above. The other way around this was created a loop to read until the comma then store as one value, then read till the newline and store as the second value. Is there a more efficient way to read from my serial device?

    Thanks,
    Chris

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    read() doesn't know what a newline is, or any other such character.

    There are some ways that you can get "processed" input using functions like read() and write().

    It generally involves "termios":
    termios - Linux Command - Unix Command

    Generally, speaking, code that I've written that use serial port reads a character at a time, and recognize whatever control characters are necessary in the code myself.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    Using read for reading a tty is normal, but the device should be opened in O_NONBLOCK mode. Next, the user is responsible for gathering data and processing it on the fly. This is normally done with something like sscanf() or the like.

    read() returns the number read from the "file". It can return 0 if in non-block mode and the user should check errno to ensure that the return value is -EAGAIN and not some other funky error. However, if any other error comes through, read _should_ return a negative value.

    There are cases where reading a character at a time could really screw you up. In the event that you have a really busy system and a slow processor, you could loose data. I would stick with read() into a nominal (2048) sized buffer then process the data from that buffer.

    EDIT: One other caveat is that you'll have to supply the '\0' at the end of the buffer prior to using sscanf(), etc.

    $0.02
    Andy
    Last edited by Kennedy; 06-16-2009 at 01:10 PM.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Kennedy View Post
    There are cases where reading a character at a time could really screw you up. In the event that you have a really busy system and a slow processor, you could loose data. I would stick with read() into a nominal (2048) sized buffer then process the data from that buffer.
    This is true. I never had any problem in my systems (486 @ 133MHz running linux or SparcStation systems, as well as 68K and 29K on RTOS systems - although in the RTOS, I wrote the interrupt handler code, so I would gather up a packet there - these were not actually lines, as it was a kind of network protocol), and I doubt that unless you have a system with severely too little memory (so the kernel is constantly swapping), you could actually make a serial port overflow on a reasonably new processor - after all, a 16550 UART needs to interrupt once every (10 [bits] * 16 [buffer size]) / 115200 times per second - about 720 times a second. That's just under 1.4 milliseconds between each interrupt (and the serial port is acutally issuing the interrupt when the first or eighth character arrives, so ther's either 15/16th of 1.4 milliseconds, or 0.7 milliseconds for the processor to respond to the interrupt). If the processor can't cope with that, it's either running at lower than 100MHz [hard to find], or is so heavily loaded that really bad things start happening elsewhere too. Bear in mind that the serial port has a low-level buffer, so once the interrupt is taken, the data is stored. An application can probably wait for many dozens of milliseconds before data is lost - maybe not seconds, but probaly a few tenths of a second would be possible, as long as the app runs for long enough once it gets to run. If that doesn't happen, then it doesn't really matter if the app reads 2K or 1 byte per system call - it will eventually loose out.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 02-02-2009, 07:27 AM
  2. Device Driver: sysfs confusion
    By filker0 in forum Linux Programming
    Replies: 0
    Last Post: 12-02-2005, 11:36 AM
  3. Linux device files
    By ojschubert in forum C Programming
    Replies: 4
    Last Post: 04-25-2005, 10:41 AM
  4. Please help with serial communication problem - Long
    By spdylude in forum Windows Programming
    Replies: 3
    Last Post: 04-06-2005, 09:41 AM
  5. Serial Communications in C
    By ExDigit in forum Windows Programming
    Replies: 7
    Last Post: 01-09-2002, 10:52 AM