一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

[翻譯] 第四章,高級串口編程

 王王王中王王王 2013-09-25

Chapter 4, Advanced Serial Programming
第四章,高級串口編程

Carol: 已獲原作者簡體中文翻譯授權(quán)。
為避免重復(fù)勞動,愿意參與翻譯的朋友請直接與我聯(lián)系 puccacarol AT hotmail DOT com
原文名稱:Serial Programming Guide for POSIX Operating Systems
<
http://www./~mike/serial/>
此翻譯為初稿,語言較粗糙,不斷完善中。。。 歡迎大家提出寶貴意見。

This chapter covers advanced serial programming techniques using the ioctl(2) and select(2) system calls.

Serial Port IOCTLs

In Chapter 2, Configuring the Serial Port we used the tcgetattr and tcsetattr functions to configure the serial port. Under UNIX these functions use the ioctl(2) system call to do their magic. The ioctl system call takes three arguments:
int ioctl(int fd, int request, ...);
The fd argument specifies the serial port file descriptor. The request argument is a constant defined in the
<termios.h> header file and is typically one of the constants listed in Table 10.

本章主要談?wù)撌褂胕octl(2)和select(2)系統(tǒng)調(diào)用的高級串口編程技術(shù)。

串行端口 IOCTLs

在第二章,配置串口中我們使用了 tcgetattr 和 tcsetattr 函數(shù)來做串口的設(shè)置。在 UNIX 下,這些函數(shù)都是使用 ioctl(2) 系統(tǒng)調(diào)用來完成他們的任務(wù)的。ioctl 系統(tǒng)調(diào)用有如下三個參數(shù):

int ioctl(int fd, int request, ...);

參數(shù) fd 指定了串行端口的文件描述符。
參數(shù) request 是一個定義在 <termios.h> 頭文件里的常量,它的一些常用值都在 表10 里面定義了。

Table 10 - IOCTL Requests for Serial Ports
表10 - IOCTL 的串口調(diào)用

Request

Description

POSIX Function

TCGETS

Gets the current serial port settings.

讀取當(dāng)前的串口屬性

tcgetattr

TCSETS

Sets the serial port settings immediately

設(shè)置串口屬性并立即生效

tcsetattr(fd, TCSANOW, &options)

TCSETSF

Sets the serial port settings after flushing the input and output buffers.

設(shè)置串口屬性,等到輸入輸出緩沖區(qū)都清空了再生效

tcsetattr(fd, TCSAFLUSH, &options)

TCSETSW

Sets the serial port settings after allowing the input and output buffers to drain/empty.

設(shè)置串口屬性,等到允許清空輸入輸出緩沖區(qū)了或數(shù)據(jù)傳完后設(shè)置生效

tcsetattr(fd, TCSADRAIN, &options)

TCSBRK

Sends a break for the given time.

在指定時間后發(fā)送break

tcsendbreak, tcdrain

TCXONC

Controls software flow control.

控制軟件流控

tcflow

TCFLSH

Flushes the input and/or output queue.

將輸入輸出隊列全部發(fā)出

tcflush

TIOCMGET

Returns the state of the "MODEM" bits.

返回 “MODEM” 位的狀態(tài)

None

TIOCMSET

Sets the state of the "MODEM" bits.

設(shè)置“MODEM”位的狀態(tài)

None

FIONREAD

Returns the number of bytes in the input buffer.

返回輸入緩沖區(qū)內(nèi)的字節(jié)數(shù)

None

Getting the Control Signals

The TIOCMGET ioctl gets the current "MODEM" status bits, which consist of all of the RS-232 signal lines except RXD and TXD, listed in Table 11.
To get the status bits, call ioctl with a pointer to an integer to hold the bits, as shown in Listing 5.

獲得控制信號
TIOCMGET - ioctl 獲得當(dāng)前“MODEM”的狀態(tài)位,其中包括了除 RXD 和 TXD 之外,所有的RS-232 信號線,見列表 11。
為了獲得狀態(tài)位,使用一個包含比特位的整數(shù)的指針來調(diào)用 ioctl,見清單5。

Listing 5 - Getting the MODEM status bits.
清單 5 - 讀取 DODEM 的狀態(tài)位.
#include <unistd.h>
#include <termios.h>
int fd;
int status;
ioctl(fd, TIOCMGET, &status);
 

Table 11 - Control Signal Constants
表 11 - 控制信號常量

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)

Setting the Control Signals
The TIOCMSET ioctl sets the "MODEM" status bits defined above. To drop the DTR signal you can use the code in Listing 6.

設(shè)置控制信號
TIOCMSET - ioctl 設(shè)置“MODEM”上述定義的狀態(tài)位??梢允褂?清單6 的代碼來給DTR信號置低。

Listing 6 - Dropping DTR with the TIOCMSET ioctl.
清單 6 - 使用 TIOCMSET ioctl 置低 DTR 信號
#include <unistd.h>
#include <termios.h>
int fd; int status;
ioctl(fd, TIOCMGET, &status);
status &= ~TIOCM_DTR;
ioctl(fd, TIOCMSET, &status);
 

The bits that can be set depend on the operating system, driver, and modes in use. Consult your operating system documentation for more information.

能進(jìn)行設(shè)置的比特位有操作系統(tǒng),驅(qū)動以及使用的模式?jīng)Q定。查詢你的操作系統(tǒng)的檔案可以獲取更多的信息。

Getting the Number of Bytes Available
The FIONREAD ioctl gets the number of bytes in the serial port input buffer. As with TIOCMGET you pass in a pointer to an integer to hold the number of bytes, as shown in Listing 7.

獲取可供讀取的字節(jié)數(shù)
FIONREAD - ioctl 讀取串行端口輸入緩沖區(qū)中的字節(jié)數(shù)。與 TIOCMGET 一起傳遞一個包含字節(jié)數(shù)的整數(shù)的指針,如 清單7 所示。

Listing 7 - Getting the number of bytes in the input buffer.
清單7 - 讀取串行端口輸入緩沖區(qū)中的字節(jié)數(shù)
#include <unistd.h>
#include <termios.h>
int fd;
int bytes;
ioctl(fd, FIONREAD, &bytes);
 

This can be useful when polling a serial port for data, as your program can determine the number of bytes in the input buffer before attempting a read.
在查詢串口是否有數(shù)據(jù)到來的時候這一段是很有用的,可以讓程序在準(zhǔn)備讀取之前用來確定輸入緩沖區(qū)里面的可讀字節(jié)數(shù)。

Selecting Input from a Serial Port
While simple applications can poll or wait on data coming from the serial port, most applications are not simple and need to handle input from multiple sources.
UNIX provides this capability through the select(2) system call. This system call allows your program to check for input, output, or error conditions on one or more file descriptors. The file descriptors can point to serial ports, regular files, other devices, pipes, or sockets. You can poll to check for pending input, wait for input indefinitely, or timeout after a specific amount of time, making the select system call extremely flexible.
Most GUI Toolkits provide an interface to select; we will discuss the X Intrinsics ("Xt") library later in this chapter.

從串行端口選擇輸入
雖然簡單的程序可以通過poll串口或者等待串口數(shù)據(jù)到來讀取串口,大多數(shù)的程序卻并不這么簡單,有時候需要處理來自多個源的輸入。
UNIX 通過 select(2) 系統(tǒng)調(diào)用提供了這種能力。這個系統(tǒng)調(diào)用允許你的程序從一個或多個文件描述符獲取輸入/輸出或者錯誤信息。文件描述符可以指向串口,普通文件,其他設(shè)備,管道,或者socket 。你可以查詢待處理的輸入,等待不確定的輸入,或者在一指定的超時到達(dá)后超時退出,這些都使得 select 系統(tǒng)調(diào)用非常的靈活。
大多數(shù)的 GUI 工具提供一個借口指向 select,我們會在本章后面的部分討論 X Intrinsics 庫(“Xt”)。


The SELECT System Call
The select system call accepts 5 arguments:
int select(int max_fd, fd_set *input, fd_set *output, fd_set *error, struct timeval *timeout);
The max_fd argument specifies the highest numbered file descriptor in the input, output, and error sets. The input, output, and error arguments specify sets of file descriptors for pending input, output, or error conditions; specify NULL to disable monitoring for the corresponding condition. These sets are initialized using three macros:
FD_ZERO(fd_set);
FD_SET(fd, fd_set);
FD_CLR(fd, fd_set);
The FD_ZERO macro clears the set entirely. The FD_SET and FD_CLR macros add and remove a file descriptor from the set, respectively.
The timeout argument specifies a timeout value which consists of seconds (timeout.tv_sec) and microseconds (timeout.tv_usec). To poll one or more file descriptors, set the seconds and microseconds to zero. To wait indefinitely specify NULL for the timeout pointer.
The select system call returns the number of file descriptors that have a pending condition, or -1 if there was an error.

SELECT 系統(tǒng)調(diào)用
Select 系統(tǒng)調(diào)用可以接受 5 個參數(shù):

int select(int max_fd, fd_set *input, fd_set *output, fd_set *error, struct timeval *timeout);

參數(shù) max_fd 定義了所有用到的文件描述符(input, output, error集合)中的最大值。
參數(shù) input, output, error 定義了待處理的輸入,輸出,錯誤情況;置 NULL 則代表不去監(jiān)查相應(yīng)的條件。這幾個集合用三個宏來進(jìn)行初始化
FD_ZERO(fd_set);
FD_SET(fd, fd_set);
FD_CLR(fd, fd_set);
宏 FD_ZERO 清空整個集合; FD_SET 和 FD_CLR 分別從集合中添加、刪除文件描述符。
參數(shù) timeout 定義了一個由秒(timeout.tv_sec)和毫秒(timeout.tv_usec)組成的一個超時值。要查詢一個或多個文件描述符,把秒和毫秒置為 0 。要無限等待的話就把 timeout 指針置 NULL 。
select 系統(tǒng)調(diào)用返回那個有待處理條件的文件描述符的值,或者,如果有錯誤發(fā)生的話就返回 -1。

Using the SELECT System Call
Suppose we are reading data from a serial port and a socket. We want to check for input from either file descriptor, but want to notify the user if no data is seen within 10 seconds. To do this we'll need to use the select system call, as shown in Listing 8.

使用 select 系統(tǒng)調(diào)用
假設(shè)我們正在從一個串口和一個socket 讀取數(shù)據(jù)。我們想確認(rèn)來自各文件描述符的輸入,又希望如果10秒鐘內(nèi)都沒有數(shù)據(jù)的話通知用戶。要完成這些工作,我們可以像 清單8 這樣使用select系統(tǒng)調(diào)用:

Listing 8 - Using SELECT to process input from more than one source.
清單8 - 使用select 處理來自多個源的輸入
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/select.h>
int n;
int socket;
int fd;
int max_fd;
fd_set input;
struct timeval timeout; /* Initialize the input set 初始化輸入集合*/
FD_ZERO(input);
FD_SET(fd, input);
FD_SET(socket, input);
max_fd = (socket > fd ? socket : fd) + 1; /* Initialize the timeout structure 初始化 timeout 結(jié)構(gòu)*/
timeout.tv_sec = 10;
timeout.tv_usec = 0;
/* Do the select */
n = select(max_fd, &input, NULL, NULL, &timeout);
/* See if there was an error 看看是否有錯誤發(fā)生*/
if (n < 0)
  perror("select failed");
else if (n == 0)
  puts("TIMEOUT");
else { /* We have input 有輸入進(jìn)來了*/
  if (FD_ISSET(fd, input))
    process_fd();
  if (FD_ISSET(socket, input))
    process_socket(); 
}  

You'll notice that we first check the return value of the select system call. Values of 0 and -1 yield the appropriate warning and error messages. Values greater than 0 mean that we have data pending on one or more file descriptors.
To determine which file descriptor(s) have pending input, we use the FD_ISSET macro to test the input set for each file descriptor. If the file descriptor flag is set then the condition exists (input pending in this case) and we need to do something.

你會發(fā)現(xiàn),我們首先檢查select系統(tǒng)調(diào)用的返回值。如果是 0 和 -1 則表示相應(yīng)的警告和錯誤信息。大于 0 的值代表我們在一個或多個文件描述符上有待處理的數(shù)據(jù)。
要知道是哪個文件描述符有待處理的輸入,我們要使用 FDISSET 宏來測試每個文件描述符的輸入集合。如果文件描述符標(biāo)志被設(shè)置了,則符合條件(這時候就有待處理的輸入了)我們需要進(jìn)行一些操作。

Using SELECT with the X Intrinsics Library
The X Intrinsics library provides an interface to the select system call via the XtAppAddInput(3x) and XtAppRemoveInput(3x) functions:
int XtAppAddInput(XtAppContext context, int fd, int mask, XtInputProc proc, XtPointer data);
void XtAppRemoveInput(XtAppContext context, int input);
The select system call is used internally to implement timeouts, work procedures, and check for input from the X server. These functions can be used with any Xt-based toolkit including Xaw, Lesstif, and Motif.
The proc argument to XtAppAddInput specifies the function to call when the selected condition (e.g. input available) exists on the file descriptor. In the previous example you could specify the process_fd or process_socket functions.
Because Xt limits your access to the select system call, you'll need to implement timeouts through another mechanism, probably via XtAppAddTimeout(3x).

在X Intrinsics library 中使用select
X Intrinsics library 提供了一個接口,通過 XtAppAddInput(3x) 和 XtAppRemoveInput(3x) 函數(shù)來使用 select 系統(tǒng)調(diào)用。
int XtAppAddInput(XtAppContext context, int fd, int mask, XtInputProc proc, XtPointer data);
void XtAppRemoveInput(XtAppContext context, int input);
select 系統(tǒng)調(diào)用是用來實現(xiàn)內(nèi)部的超時,工作過程,并且檢查來自 X Server 的輸入。這些函數(shù)可以在任何 基于Xt 的工具上使用,包括Xaw, Lesstif, 和 Motif。
XtAppAddInput 的參數(shù) proc 定義了當(dāng)某一個文件描述符上的select條件滿足時函數(shù)的調(diào)用(比如有輸入進(jìn)來)。在之前的例子里,你可以定義process_fd 或 processs_socket 函數(shù)。
由于 Xt 限制了你對 select 系統(tǒng)調(diào)用的訪問,你需要通過其他機制實現(xiàn)超時,可以通過 XtAppAddTimeout(3x)。


 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    国产不卡的视频在线观看| 日本免费熟女一区二区三区| 在线观看国产成人av天堂野外| 日本高清一道一二三区四五区 | 久久中文字人妻熟女小妇| 青青草草免费在线视频| 欧美日韩国产亚洲三级理论片| 久久机热频这里只精品| 中文字幕无线码一区欧美| 中文字幕乱码免费人妻av| 一区二区三区日韩经典| 日韩专区欧美中文字幕| 九九热这里只有免费精品| 蜜桃传媒视频麻豆第一区| 国内午夜精品视频在线观看| 亚洲日本久久国产精品久久| 中国美女草逼一级黄片视频| 国内胖女人做爰视频有没有| 国产精品欧美一区二区三区| 久久99午夜福利视频| 国产av大片一区二区三区| 色综合视频一区二区观看| 日韩亚洲精品国产第二页| 少妇成人精品一区二区| 亚洲一区二区精品免费视频| 欧美黄色成人真人视频| 极品少妇嫩草视频在线观看| 国产一区二区三区丝袜不卡 | 欧美日韩亚洲巨色人妻| 国产三级不卡在线观看视频| 精品一区二区三区乱码中文| 欧美夫妻性生活一区二区| 日韩不卡一区二区在线| 国产又粗又长又大高潮视频| 99久久国产精品免费| 午夜激情视频一区二区| 可以在线看的欧美黄片| 成人午夜在线视频观看| 精品女同在线一区二区| 国产av大片一区二区三区| 五月天丁香婷婷一区二区|