fcntl, serial ports and serial signals on RS232.

Discussion in 'Python' started by Max Kotasek, Apr 7, 2010.

  1. Max Kotasek

    Max Kotasek Guest

    Hello to all out there,

    I'm trying to figure out how to parse the responses from fcntl.ioctl()
    calls that modify the serial lines in a way that asserts that the line
    is now changed. For example I may want to drop RTS explicitly, and
    assert that the line has been dropped before returning.

    Here is a brief snippet of code that I've been using to do that, but
    not sure what to do with the returned response:

    def set_RTS(self, state=True):
    if self.fd is None:
    return 0

    p = struct.pack('I', termios.TIOCM_RTS)
    if state:
    return fcntl.ioctl(self.fd, termios.TIOCMBIS, p)
    else:
    return fcntl.ioctl(self.fd, termios.TIOCMBIC, p)

    The problem is I get responses like '\x01\x00\x00\x00', or
    '\x02\x00\x00\x00' and I'm not sure what they mean. I tried doing
    illogical things like settings CTS using the TIOCM_CTS flag and I end
    up just getting back a slightly different binary packed 32 bit integer
    (in that case '\x20\x00\x00\x00'). The above example has self.fd
    being defined as os.open('/dev/ttyS0', os.O_RDWR | os.O_NONBLOCK).

    Is someone familiar with manipulating serial signals like this in
    python? Am I even taking the right approach by using the fcntl.ioctl
    call? The environment is a ubuntu 8.04 distribution. Unfortunately
    due to other limitations, I can't use/extend pyserial, though I would
    like to.

    I appreciate any advice on this matter,
    Max
    Max Kotasek, Apr 7, 2010
    #1
    1. Advertising

  2. Max Kotasek

    Anssi Saari Guest

    Max Kotasek <> writes:

    > Hello to all out there,
    >
    > I'm trying to figure out how to parse the responses from fcntl.ioctl()
    > calls that modify the serial lines in a way that asserts that the line
    > is now changed. For example I may want to drop RTS explicitly, and
    > assert that the line has been dropped before returning.
    >
    > Here is a brief snippet of code that I've been using to do that, but
    > not sure what to do with the returned response:
    >
    > def set_RTS(self, state=True):
    > if self.fd is None:
    > return 0
    >
    > p = struct.pack('I', termios.TIOCM_RTS)
    > if state:
    > return fcntl.ioctl(self.fd, termios.TIOCMBIS, p)
    > else:
    > return fcntl.ioctl(self.fd, termios.TIOCMBIC, p)
    >
    > The problem is I get responses like '\x01\x00\x00\x00', or
    > '\x02\x00\x00\x00' and I'm not sure what they mean.


    I'm not an expert in this by any means. However, I don't think that
    fcntl call actually returns the port status after the bit setting. But
    why not check it explicitly with termios.TIOCMGET? At least then I
    seem to be able to toggle the RTS bit (bit 2) in the register. Here
    are the trivial functions I used:

    def set_rts(fd):
    print "Setting RTS."
    p = struct.pack('I', termios.TIOCM_RTS)
    fcntl.ioctl(fd, termios.TIOCMBIS, p)

    def clear_rts(fd):
    print "Clearing RTS."
    p = struct.pack('I', termios.TIOCM_RTS)
    fcntl.ioctl(fd, termios.TIOCMBIC, p)

    def get_status(fd):
    print "Querying RTS state."
    stat = struct.pack('I', 0)
    rc = fcntl.ioctl(fd, termios.TIOCMGET, stat)
    if struct.unpack('I', rc)[0] & termios.TIOCM_RTS:
    print "RTS bit is on."
    else:
    print "RTS bit is off."


    It seems to me also that RTS is always on after the port has been
    opened. I didn't dig out my voltmeter or anything to check this,
    though.
    Anssi Saari, Apr 8, 2010
    #2
    1. Advertising

  3. On 2010-04-07, Max Kotasek <> wrote:

    > I'm trying to figure out how to parse the responses from fcntl.ioctl()
    > calls that modify the serial lines in a way that asserts that the line
    > is now changed.


    Two comments:

    1) None of the Linux serial drivers I've worked on return line states
    except when you call TIOCMGET.

    2) If the TIOCMBI[S|C] call returned a 'success' value, then the
    line was set to what you requested.

    If you want to read back the state that you just wrote, you can call
    TIOCMGET, but for the "output" pins it's always going to return the
    last value that was written.

    > For example I may want to drop RTS explicitly, and
    > assert that the line has been dropped before returning.


    Call TIOCMSET. If it doesn't return an error, then you're done.

    > Here is a brief snippet of code that I've been using to do that, but
    > not sure what to do with the returned response:


    What returned response?

    The only thing that is returned by TIOCMBIS/TIOCMBIC is a status value
    of 0 for success and <0 for failure. IIRC, that value is checked by
    Python's fcntl.ioctl wrapper and it will raise an exception on
    failure.

    > Is someone familiar with manipulating serial signals like this in
    > python?


    Yes.

    > Am I even taking the right approach by using the fcntl.ioctl call?


    Yes. When you set/clear RTS or DTR do they not go up/down?

    Even if you can't use pyserial, it's a good source for example code.

    --
    Grant Edwards grant.b.edwards Yow! TONY RANDALL! Is YOUR
    at life a PATIO of FUN??
    gmail.com
    Grant Edwards, Apr 8, 2010
    #3
  4. On 2010-04-08, Anssi Saari <> wrote:

    > It seems to me also that RTS is always on after the port has been
    > opened. I didn't dig out my voltmeter or anything to check this,
    > though.


    IIRC, that's generally true: RTS and DTR are both set to "on" by the
    tty layer's open() handler _if_ the device's useage count was 0. If
    you open an already open port, then the RTS and DTR lines are left
    alone.

    --
    Grant Edwards grant.b.edwards Yow! Someone in DAYTON,
    at Ohio is selling USED
    gmail.com CARPETS to a SERBO-CROATIAN
    Grant Edwards, Apr 8, 2010
    #4
  5. Max Kotasek

    Max Kotasek Guest

    On Apr 8, 11:17 am, Grant Edwards <> wrote:
    > On 2010-04-07, Max Kotasek <> wrote:
    >
    > > I'm trying to figure out how to parse the responses fromfcntl.ioctl()
    > > calls that modify the serial lines in a way that asserts that the line
    > > is now changed.

    >
    > Two comments:
    >
    >   1) None of the Linux serial drivers I've worked on return line states
    >      except when you call TIOCMGET.
    >
    >   2) If the TIOCMBI[S|C] call returned a 'success' value, then the
    >      line was set to what you requested.
    >
    > If you want to read back the state that you just wrote, you can call
    > TIOCMGET, but for the "output" pins it's always going to return the
    > last value that was written.
    >
    > > For example I may want to drop RTS explicitly, and
    > > assert that the line has been dropped before returning.

    >
    > Call TIOCMSET.  If it doesn't return an error, then you're done.
    >
    > > Here is a brief snippet of code that I've been using to do that, but
    > > not sure what to do with the returned response:

    >
    > What returned response?
    >
    > The only thing that is returned by TIOCMBIS/TIOCMBIC is a status value
    > of 0 for success and <0 for failure. IIRC, that value is checked by
    > Python'sfcntl.ioctl wrapper and it will raise an exception on
    > failure.
    >
    > > Is someone familiar with manipulating serial signals like this in
    > > python?

    >
    > Yes.
    >
    > > Am I even taking the right approach by using thefcntl.ioctl call?

    >
    > Yes.  When you set/clear RTS or DTR do they not go up/down?
    >
    > Even if you can't use pyserial, it's a good source for example code.
    >
    > --
    > Grant Edwards               grant.b.edwards        Yow! TONY RANDALL!  Is YOUR
    >                                   at               life a PATIO of FUN??
    >                               gmail.com            



    I appreciate the feedback. I'm working in an environment with a lot
    of changing factors, it's nice to have a piece not act unexpectedly.

    Max
    Max Kotasek, Apr 9, 2010
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. PaullyB

    JMS over a serial port (rs232)

    PaullyB, Feb 22, 2005, in forum: Java
    Replies:
    0
    Views:
    472
    PaullyB
    Feb 22, 2005
  2. Chris Green

    Linux, fcntl, F_SETLEASE and signals

    Chris Green, Jul 21, 2004, in forum: Python
    Replies:
    11
    Views:
    1,662
    Chris Green
    Jul 26, 2004
  3. Omid Fatemi

    fcntl and FCNTL

    Omid Fatemi, Oct 30, 2004, in forum: Python
    Replies:
    4
    Views:
    6,850
    Steve Holden
    Nov 1, 2004
  4. Mitko Haralanov

    Invalid argument with fcntl.fcntl

    Mitko Haralanov, Jun 6, 2007, in forum: Python
    Replies:
    0
    Views:
    540
    Mitko Haralanov
    Jun 6, 2007
  5. mreister
    Replies:
    1
    Views:
    3,159
    mreister
    May 25, 2010
Loading...

Share This Page