第四章 Advanced Serial Programming
本章介绍在UNIX用ioctl(2)和select(2)来完成串口编程。可以用tcgetattr和tcsetattr来配置串口,也可以用系统函数ioctl(2)来完成。
int ioctl(int fd, int request, …);
其中fd是文件描述符,request参数是定义在中的常数。
Request |
Description |
POSIX Function |
TCGETS |
获得当前串口的设置 |
tcgetattr |
TCSETS |
设置当前串口,立即起作用 |
tcsetattr(fd, TCSANOW,&options) |
TCSETSF |
设置当前串口,刷清输入输出缓冲后起作用 |
tcsetattr(fd, TCSAFLUSH, &options) |
TCSETSW |
设置当前串口,在读写完或清空后有效 |
tcsetattr(fd, TCSADRAIN, &options) |
TCSBRK |
在给定的时间发送BREAK |
tcsendbreak, tcdrain |
TCXONC |
软件流控制 |
tcflow |
TCFLSH |
刷清输入/输出队列 |
tcflush |
TIOCMGET |
返回”MODEM”位的状态 |
None |
TIOCMSET |
设置”MODEM”位的状态 |
None |
FIONREAD |
返回输入队列的字节数 |
None |
Getting the Control Signals
TIOCMGET ioctl能够返回RS232除RXD/TXD之外的信号,即如下信号
Constant |
Description |
TIOCM_LE |
DSR (data set ready/line enable) |
TIOCM_DTR |
DTR (data terminal ready) |
TIOCM_RTS |
RTS (request to send) |
TIOCM_ST |
Secondary TXD (transmit) |
TIOCM_SR |
Secondary RXD (receive) |
TIOCM_CTS |
CTS (clear to send) |
TIOCM_CAR |
DCD (data carrier detect) |
TIOCM_CD |
Synonym for TIOCM_CAR |
TIOCM_RNG |
RNG (ring) |
TIOCM_RI |
Synonym for TIOCM_RNG |
TIOCM_DSR |
DSR (data set ready) |
Listing 5-Getting the MODEM status bits
#include
#include
int fd;
int status;
ioctl(fd, TIOCMGET, &status);
Setting the Control Signals
TIOCMSET ioctl能够设置上表所示的信号。
Listing 6-Dropping DTR with the TIOCMSET ioctl
#include
#include
int fd;
int status;
ioctl(fd, TIOCMGET, &status);
status &= ~TIOCM_DTR;
ioctl(fd, TIOCMSET, &status);
Getting the Number of Bytes Available
FIONREAD ioctl能够取得串口输入缓冲区中已经有的字节。
Listing 7-Getting the number of bytes in the input buffer
#include
#include
int fd;
int bytes;
ioctl(fd, FIONREAD, &bytes);
Selecting Input from a Serial Port
一般情况下,不需要处理输入缓冲或者是输出缓冲。UNIX提供了select(2)函数来完成对文件描述符关于输入,输入,或者出错的检查。当然,文件描述符可以是串口,正规文件,管道,或者是socket。
int select(int max_fd, fd_set *input, fd_set *output, fd_set *error, struct timeval *timeout);
FD_ZERO(&fd_set);
FD_SET(fd, &fd_set);
FD_CLR(fd, &fd_set);
Using the SELECT System Call
Listing 8-Usin SELECT to process input from more than one source.
#include
#include
#include
#include
int n;
int socket;
int fd;
int max_fd;
fd_set input;
struct timeval timeout;
/* Initialize the input */
FD_ZERO(&input);
FD_SET(fd, &input);
FD_SET(sock, &input);
max_fd = (sock > fd? sock:fd) + 1;
/* Initialize the timeout structure */
timeout.tv_sec = 10;
tiemout.tv_usec = 0;
/* Do the select */
n = select(max_fd, &input, NULL, NULL, &timeout);
/* see it there was an error */
if(n < 0)
perror(“select failed”);
else if(n == 0)
puts(“TIMEOUT”);
else
{
/* we have input */
if(FD_ISSET(fd, &input))
process_fd();
if(FD_ISSET(sock, &input))
process_socket();
}
Using SELECT with the X Instrinsics Library
X Instrinsics library为select系统函数提供了一些接口
int XtAppAddInput(XtAppContext context, int fd, int mask, XtInputProc proc, XtPointer data);
void XtAppRemoveInput(XtAppContext context, int input);
阅读(1301) | 评论(0) | 转发(0) |