当前位置: 技术问答>linux和unix
请高手指路。
来源: 互联网 发布时间:2014-10-28
本文导语: 我使用SCO UNIX做服务器,并发接收客户端发过来的数据包,通过对数据包的翻译,拼成一条交换机的指令,通过串口发到交换机上去运行并得到运行后的返回信息。 问题:怎么通过串口将指令发到交换机上运行并得...
我使用SCO UNIX做服务器,并发接收客户端发过来的数据包,通过对数据包的翻译,拼成一条交换机的指令,通过串口发到交换机上去运行并得到运行后的返回信息。
问题:怎么通过串口将指令发到交换机上运行并得到返回信息。
问题:怎么通过串口将指令发到交换机上运行并得到返回信息。
|
你可以参照:Serial-Programming-HOWTO(最新的可以从www.linuxdoc.org获得)
另外,你也可以参照mgetty(ftp://alpha.greenie.net/pub/mgetty/source/1.1/mgetty1.1.26-Apr16.tar.gz, http://alpha.greenie.net/mgetty/)的源码, 写得不错。
另外,你也可以参照mgetty(ftp://alpha.greenie.net/pub/mgetty/source/1.1/mgetty1.1.26-Apr16.tar.gz, http://alpha.greenie.net/mgetty/)的源码, 写得不错。
|
用ioctl设置好通信参数;
使用open,read,write,close对《/dev/串口设备名》(不同unix名可能不同) 编程,
对不起,一直没条件实验
使用open,read,write,close对《/dev/串口设备名》(不同unix名可能不同) 编程,
对不起,一直没条件实验
|
或termios
|
3.6 How to handle a serial port or modem?
=========================================
The handling of serial devices under Unix is heavily influenced by the
traditional use of serial terminals. Historically, various combinations of
ioctls and other hacks were necessary to control the precise behaviour of a
serial device, but fortunately this is one of the areas that POSIX made
some efforts to standardise.
If you're using a system that doesn't understand `',
`tcsetattr()' and related functions, then you'll have to go elsewhere for
information (or upgrade your system to something less archaeological).
There are still significant differences between systems, however, mainly in
the area of device names, handling of hardware flow control, and modem
signalling. (Whenever possible, leave the device driver to do all the
handshaking work, and don't attempt to manipulate handshaking signals
directly.)
The basic steps for opening and initialising a serial device are:
* `open()' the device; this may require the use of certain flags:
`O_NONBLOCK'
Opening a dial-in or modem-controlled device will block until
carrier is present, unless this flag is used. A nonblocking open
gives you the opportunity to disable the modem controls (see
CLOCAL below) if necessary.
`O_NOCTTY'
On 4.4BSD-derived systems this is redundant, but on other systems
it controls whether the serial device can become a control
terminal for the session. In most cases you probably *don't* want
to acquire a control terminal, and should therefore specify this
flag, but there are exceptions.
* Use `tcgetattr()' to retrieve the current device modes. While one will
often ignore most or all of the initial settings thus obtained, it's
still a convenient way of initialising a `struct termios'.
* Set suitable values for `c_iflag', `c_oflag', `c_cflag', `c_lflag',
and `c_cc' in the termios structure. (See below.)
* Use `cfsetispeed()' and `cfsetospeed()' to set the desired baud rate.
Very few systems allow you to set differing input and output speeds,
so as a general rule you should set both to your desired speed.
* Use `tcsetattr()' to set the device modes.
* You may wish, if you used `O_NONBLOCK' when opening the port, to use
`fcntl()' to ensure that `O_NONBLOCK' is turned off again. Systems
seem to differ as to whether a nonblocking open on a tty will affect
subsequent `read()' calls; better to be explicit.
Once you have opened and set up the port, you can then use `read()' and
`write()' normally. Note that the behaviour of `read()' will be controlled
by the flag settings you gave to `tcsetattr()'.
`tcflush()', `tcdrain()', `tcsendbreak()' and `tcflow()' are additional
useful functions that you should be aware of.
When you're done with the port, and want to close it, be aware of a very
nasty little hazard on some systems; if there's any pending output waiting
to be written to the device (e.g. if output flow is stopped by hardware or
software handshaking), your process can hang *unkillably* in the `close()'
call until the output drains. Calling `tcflush()' to discard any pending
output is probably a wise move.
(Blocked output on tty devices is by far the most common cause of
"unkillable" processes in my experience.)
3.6.1 Serial device names and types
-----------------------------------
The device names used for serial port devices vary quite widely between
systems. Some examples from different systems are:
* `/dev/tty[0-9][a-z]' for direct access devices, and
`/dev/tty[0-9][A-Z]' for modem control devices (e.g. SCO Unix)
* `/dev/cua[0-9]p[0-9]' for direct access devices, `/dev/cul[0-9]p[0-9]'
for dial-out devices and `/dev/ttyd[0-9]p[0-9]' for dial-in devices
(e.g. HP-UX)
* `/dev/cua[a-z][0-9]' for dial-out devices and `/dev/tty[a-z][0-9]' for
dial-in devices (e.g. FreeBSD)
The precise interaction between the device name used, and the effect on any
hardware handshake lines is system-, configuration- and hardware-dependant,
but will usually follow approximately these rules (assuming that the
hardware is RS-232 DTE):
- A successful open of any device should assert DTR and RTS
- A blocking open of a modem-control or dial-in device will wait for DCD
(and possibly also DSR and/or CTS) to be raised, usually after
asserting DTR/RTS.
- An open of a dial-out device while an open call to the corresponding
dial-in device is blocked waiting for carrier *may or may not* cause
the open of the dial-in port to complete. Some systems implement a
simple sharing scheme for dial-in and dial-out ports whereby the
dial-in port is effectively "put to sleep" while the dial-out port is
in use; other systems do not do this, and sharing the port between
dial-in and dial-out on such systems requires external cooperation
(e.g. use of UUCP lockfiles) to avoid contention problems.
3.6.2 Setting up termios flags
------------------------------
Some hints on setting up the termios flags when using a serial device that
you've opened yourself (as opposed to using your existing control tty):
3.6.2.1 c_iflag
................
You probably want to set *all* the bits in `c_iflag' to 0, unless you want
to use software flow control (ick) in which case you set `IXON' and `IXOFF'.
3.6.2.2 c_oflag
................
Most of the bits of `c_oflag' are hacks of one sort or another to make
output to slow terminals work, and as such some newer systems have dropped
almost all of them as obsolete (especially all the gory output-padding
options). As with `c_iflag', setting everything to 0 is reasonable for most
applications.
3.6.2.3 c_cflag
................
When setting the character size, remember to mask using `CSIZE' first; e.g.
to set 8-bit characters, use:
attr.c_cflag &= ~CSIZE;
attr.c_cflag |= CS8;
Other important flags found in `c_cflag' that you probably want to turn
*on* and `CREAD' and `HUPCL'.
If you need to generate even parity, then set `PARENB' and clear `PARODD';
if you need to generate odd parity then set both `PARENB' and `PARODD'. If
you don't want parity at all, then make sure `PARENB' is clear.
Clear `CSTOPB' unless you actually need to generate two stop bits.
Flags for enabling hardware flow control may also be found in `c_cflag',
but they aren't standardised (pity).
3.6.2.4 c_lflag
................
Most applications will probably want to turn off `ICANON' (canonical, i.e.
line-based, input processing), `ECHO', and `ISIG'.
`IEXTEN' is a more complex issue. If you don't turn it off, the
implementation is allowed to do nonstandard things (like define additional
control characters in `c_cc') that might cause unexpected results, but you
might need to leave `IEXTEN' enabled on some systems to get useful features
like hardware flow control.
3.6.2.5 c_cc
.............
This is an array of characters that have special meanings on input. These
characters are given names like `VINTR', `VSTOP' etc.; the names are
indexes into the array.
(Two of these "characters" are not really characters at all, but control
the behaviour of `read()' when `ICANON' is disabled; these are `VMIN' and
`VTIME'.)
The indexes are often referred to as though they were actual variables,
e.g. "set VMIN to 1" actually means "set c_cc[VMIN] to 1". The shorthand is
useful and only occasionally confusing.
Many of the slots in `c_cc' are only used if some other combination of
flags is set:
Used only if `ICANON' is set
`VEOF', `VEOL', `VERASE', `VKILL' (and also `VEOL2', `VSTATUS' and
`VWERASE' if defined and `IEXTEN' is set)
Used only if `ISIG' is set
`VINTR', `VQUIT', `VSUSP' (and also `VDSUSP' if defined and `IEXTEN'
is set)
Used only if `IXON' or `IXOFF' is set
`VSTOP', `VSTART'
Used only if `ICANON' is *not* set
`VMIN', `VTIME'
Implementations may define additional entries in `c_cc'. It may be prudent
to initialise all the entries to `_POSIX_VDISABLE' (the constant `NCCS'
gives the array size) before setting the specific values you wish to use.
`VMIN' and `VTIME' (which may share slots with `VEOF' and `VEOL'
respectively, depending on the implementation) have the following meaning.
The value of `VTIME' is (if not 0) always interpreted as a timer in tenths
of seconds.
`c_cc[VMIN] > 0, c_cc[VTIME] > 0'
`read()' will return when either VMIN bytes of input are available, or
if at least one character has been read and VTIME has expired between
characters, or if interrupted by a signal.
`c_cc[VMIN] > 0, c_cc[VTIME] == 0'
`read()' will return when VMIN bytes of input are available, or if
interrupted. Otherwise it will wait indefinitely.
`c_cc[VMIN] == 0, c_cc[VTIME] > 0'
`read()' will return as soon as any input is available; if VTIME
expires with no data arriving, it will return with no characters read.
(This conflicts slightly with the end-of-file indication received in
the event of modem hangup; using 1 for VMIN and either `alarm()' or
`select()' for a timeout avoids this particular problem.)
`c_cc[VMIN] == 0, c_cc[VTIME] == 0'
`read()' will always return immediately; if no data is available it
will return with no characters read (with the same problem as above).
=========================================
The handling of serial devices under Unix is heavily influenced by the
traditional use of serial terminals. Historically, various combinations of
ioctls and other hacks were necessary to control the precise behaviour of a
serial device, but fortunately this is one of the areas that POSIX made
some efforts to standardise.
If you're using a system that doesn't understand `',
`tcsetattr()' and related functions, then you'll have to go elsewhere for
information (or upgrade your system to something less archaeological).
There are still significant differences between systems, however, mainly in
the area of device names, handling of hardware flow control, and modem
signalling. (Whenever possible, leave the device driver to do all the
handshaking work, and don't attempt to manipulate handshaking signals
directly.)
The basic steps for opening and initialising a serial device are:
* `open()' the device; this may require the use of certain flags:
`O_NONBLOCK'
Opening a dial-in or modem-controlled device will block until
carrier is present, unless this flag is used. A nonblocking open
gives you the opportunity to disable the modem controls (see
CLOCAL below) if necessary.
`O_NOCTTY'
On 4.4BSD-derived systems this is redundant, but on other systems
it controls whether the serial device can become a control
terminal for the session. In most cases you probably *don't* want
to acquire a control terminal, and should therefore specify this
flag, but there are exceptions.
* Use `tcgetattr()' to retrieve the current device modes. While one will
often ignore most or all of the initial settings thus obtained, it's
still a convenient way of initialising a `struct termios'.
* Set suitable values for `c_iflag', `c_oflag', `c_cflag', `c_lflag',
and `c_cc' in the termios structure. (See below.)
* Use `cfsetispeed()' and `cfsetospeed()' to set the desired baud rate.
Very few systems allow you to set differing input and output speeds,
so as a general rule you should set both to your desired speed.
* Use `tcsetattr()' to set the device modes.
* You may wish, if you used `O_NONBLOCK' when opening the port, to use
`fcntl()' to ensure that `O_NONBLOCK' is turned off again. Systems
seem to differ as to whether a nonblocking open on a tty will affect
subsequent `read()' calls; better to be explicit.
Once you have opened and set up the port, you can then use `read()' and
`write()' normally. Note that the behaviour of `read()' will be controlled
by the flag settings you gave to `tcsetattr()'.
`tcflush()', `tcdrain()', `tcsendbreak()' and `tcflow()' are additional
useful functions that you should be aware of.
When you're done with the port, and want to close it, be aware of a very
nasty little hazard on some systems; if there's any pending output waiting
to be written to the device (e.g. if output flow is stopped by hardware or
software handshaking), your process can hang *unkillably* in the `close()'
call until the output drains. Calling `tcflush()' to discard any pending
output is probably a wise move.
(Blocked output on tty devices is by far the most common cause of
"unkillable" processes in my experience.)
3.6.1 Serial device names and types
-----------------------------------
The device names used for serial port devices vary quite widely between
systems. Some examples from different systems are:
* `/dev/tty[0-9][a-z]' for direct access devices, and
`/dev/tty[0-9][A-Z]' for modem control devices (e.g. SCO Unix)
* `/dev/cua[0-9]p[0-9]' for direct access devices, `/dev/cul[0-9]p[0-9]'
for dial-out devices and `/dev/ttyd[0-9]p[0-9]' for dial-in devices
(e.g. HP-UX)
* `/dev/cua[a-z][0-9]' for dial-out devices and `/dev/tty[a-z][0-9]' for
dial-in devices (e.g. FreeBSD)
The precise interaction between the device name used, and the effect on any
hardware handshake lines is system-, configuration- and hardware-dependant,
but will usually follow approximately these rules (assuming that the
hardware is RS-232 DTE):
- A successful open of any device should assert DTR and RTS
- A blocking open of a modem-control or dial-in device will wait for DCD
(and possibly also DSR and/or CTS) to be raised, usually after
asserting DTR/RTS.
- An open of a dial-out device while an open call to the corresponding
dial-in device is blocked waiting for carrier *may or may not* cause
the open of the dial-in port to complete. Some systems implement a
simple sharing scheme for dial-in and dial-out ports whereby the
dial-in port is effectively "put to sleep" while the dial-out port is
in use; other systems do not do this, and sharing the port between
dial-in and dial-out on such systems requires external cooperation
(e.g. use of UUCP lockfiles) to avoid contention problems.
3.6.2 Setting up termios flags
------------------------------
Some hints on setting up the termios flags when using a serial device that
you've opened yourself (as opposed to using your existing control tty):
3.6.2.1 c_iflag
................
You probably want to set *all* the bits in `c_iflag' to 0, unless you want
to use software flow control (ick) in which case you set `IXON' and `IXOFF'.
3.6.2.2 c_oflag
................
Most of the bits of `c_oflag' are hacks of one sort or another to make
output to slow terminals work, and as such some newer systems have dropped
almost all of them as obsolete (especially all the gory output-padding
options). As with `c_iflag', setting everything to 0 is reasonable for most
applications.
3.6.2.3 c_cflag
................
When setting the character size, remember to mask using `CSIZE' first; e.g.
to set 8-bit characters, use:
attr.c_cflag &= ~CSIZE;
attr.c_cflag |= CS8;
Other important flags found in `c_cflag' that you probably want to turn
*on* and `CREAD' and `HUPCL'.
If you need to generate even parity, then set `PARENB' and clear `PARODD';
if you need to generate odd parity then set both `PARENB' and `PARODD'. If
you don't want parity at all, then make sure `PARENB' is clear.
Clear `CSTOPB' unless you actually need to generate two stop bits.
Flags for enabling hardware flow control may also be found in `c_cflag',
but they aren't standardised (pity).
3.6.2.4 c_lflag
................
Most applications will probably want to turn off `ICANON' (canonical, i.e.
line-based, input processing), `ECHO', and `ISIG'.
`IEXTEN' is a more complex issue. If you don't turn it off, the
implementation is allowed to do nonstandard things (like define additional
control characters in `c_cc') that might cause unexpected results, but you
might need to leave `IEXTEN' enabled on some systems to get useful features
like hardware flow control.
3.6.2.5 c_cc
.............
This is an array of characters that have special meanings on input. These
characters are given names like `VINTR', `VSTOP' etc.; the names are
indexes into the array.
(Two of these "characters" are not really characters at all, but control
the behaviour of `read()' when `ICANON' is disabled; these are `VMIN' and
`VTIME'.)
The indexes are often referred to as though they were actual variables,
e.g. "set VMIN to 1" actually means "set c_cc[VMIN] to 1". The shorthand is
useful and only occasionally confusing.
Many of the slots in `c_cc' are only used if some other combination of
flags is set:
Used only if `ICANON' is set
`VEOF', `VEOL', `VERASE', `VKILL' (and also `VEOL2', `VSTATUS' and
`VWERASE' if defined and `IEXTEN' is set)
Used only if `ISIG' is set
`VINTR', `VQUIT', `VSUSP' (and also `VDSUSP' if defined and `IEXTEN'
is set)
Used only if `IXON' or `IXOFF' is set
`VSTOP', `VSTART'
Used only if `ICANON' is *not* set
`VMIN', `VTIME'
Implementations may define additional entries in `c_cc'. It may be prudent
to initialise all the entries to `_POSIX_VDISABLE' (the constant `NCCS'
gives the array size) before setting the specific values you wish to use.
`VMIN' and `VTIME' (which may share slots with `VEOF' and `VEOL'
respectively, depending on the implementation) have the following meaning.
The value of `VTIME' is (if not 0) always interpreted as a timer in tenths
of seconds.
`c_cc[VMIN] > 0, c_cc[VTIME] > 0'
`read()' will return when either VMIN bytes of input are available, or
if at least one character has been read and VTIME has expired between
characters, or if interrupted by a signal.
`c_cc[VMIN] > 0, c_cc[VTIME] == 0'
`read()' will return when VMIN bytes of input are available, or if
interrupted. Otherwise it will wait indefinitely.
`c_cc[VMIN] == 0, c_cc[VTIME] > 0'
`read()' will return as soon as any input is available; if VTIME
expires with no data arriving, it will return with no characters read.
(This conflicts slightly with the end-of-file indication received in
the event of modem hangup; using 1 for VMIN and either `alarm()' or
`select()' for a timeout avoids this particular problem.)
`c_cc[VMIN] == 0, c_cc[VTIME] == 0'
`read()' will always return immediately; if no data is available it
will return with no characters read (with the same problem as above).