[Translation] Chapter 4, Advanced Serial Programming - Use IOCTL and SELECT

xiaoxiao2021-03-06  63

Chapter 4, Advanced Serial Programming Chapter 4, Advanced Serial Programming

Carol: The original author's Simplified Chinese translation authorization. In order to avoid duplication of labor, please contact me to contact me directly with me, please contact me: Serial Programming Guide for Posix Operating Systems This translation The first draft, the language is rough, and it is constantly improving. . . Welcome everyone to make valuable comments. This Chapter Covers Advanced Serial Programming Techniques Using The IOCTL (2) And SESTEM CALLS.

Serial Port IOCTLsIn 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 header file and is typically one of the constants listed in Table 10..

This chapter focuses on the use of IOCTL (2) and SELECT (2) system calls to advanced serial programming technology.

Serial Port IOCTLS In Chapter 2, configuring serial ports we use Tcgetattr and TCSetattr functions to make serial port settings. Under UNIX, these functions are used using IOCTL (2) system calls to complete their tasks. The IOCTL system call has three parameters: int ioctl (int FD, int REQUEST, ...); parameter FD specifies the file descriptor of the serial port. Parameters Request is a constant defined in the header file in the , and some of its common values ​​are defined in Table 10.

Table 10 - IOCTL REQUESTS for Serial Ports Table 10 - Serial Call for IOCTL

REQUEST

Description

POSIX FUNCTION

Tcgets

Gets The Current Serial Port Settings.

Read the current serial attribute

Tcgetattr

TCSETS

Sets The Serial Port Settings Immediately

Set the serial port attribute and take effect immediately

TcSetattr (FD, Tcsanow, & Options)

TCSETSF

Sets The Serial Port Settings After Flushing The Input and Output Buffers.

Set the serial port properties, wait until the input and output buffer clears the regeneration

TcSetattr (FD, TCSAFLUSH, & OPTIONS)

TCSETSW

Sets The Serial Port Settings After Afterowing The Input and Output Buffers to Drain / Empty.

Set the serial attribute, wait until the empty input / output buffer is allowed to set the time-finished setup, set the effect TcSetattr (FD, TCSADRAIN, & OPTIONS)

TCSBRK

Sends a Break for the Given Time.

Send BREAK after specifying time

TcsendBreak, Tcdrain

TCXONC

Controls Software Flow Control.

Control software flow control

Tcflow

TCFLSH

Flushes the input and / or output queue.

All input and output queues

Tcflush

Tiocmget

Returns The State of The "Modem" bits.

Returns the status of the "MODEM" bit

None

Tiocmset

Sets The State of The "Modem" bits.

Set the status of the "MODEM" bit

None

FionRead

Returns the Number of bytes in the input buffer.

Returns the number of bytes in the input buffer

None

Getting the Control SignalsThe 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.

The control signal TiOCMGET - IOCTL is obtained to obtain the status bit of the current "modem", including all RS-232 signal lines, all of which are listed 11 in addition to RXD and TXD. In order to obtain a status bit, use a pointer to an integer of a bit to call IOCTL, see Listing 5.

Listing 5 - Getting The Modem Status Bits. Listing 5 - Reading DODEM status bits. #Include #include int fd; int status; ioctl (fd, tiocmget, & status);

TABLE 11 - Control Signal Constants Table 11 - Control Signal Convection

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

Synynym for tiocm_car

TiOCM_RNG

RNG (RING)

TiOCM_RI

Synynym for tiocm_rng

Tiocm_DSR

DSR (Data Set Ready)

Setting The Control Signalsthe Tiocmset IOCTL Sets The "Modem" status bits defined Above. To Drop The DTR Signal You Can Use the code in listing 6.

Set the control signal TiocMset - IOCTL Set the status bit of the above-described definition described above. You can use the code of the list 6 to set the DTR signal. Listing 6 - DROPPING DTR with the TIOCMSET IOCTL. Listing 6 - Remarks Low DTR Signal #include #include Int Fd; IOCTL (FD, Tiocmit, & 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.

The bit-specific bitmap is determined by the schedule of the bit. Check your operating system files to get more information.

Getting the Number of Bytes AvailableThe 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.

Get the number of bytes available to read the number of bytes to read the number of bytes in the serial port input buffer. Commanded a pointer with an integer containing the number of bytes along with the TiocMget, as shown in Listing 7.

Listing 7 - Getting the number of bytes in the input buffer. Listing 7 - Read the number of bytes in the serial port input buffer #include #include 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 ATTEMPTING A Read. This section is very useful when querying the serial port is available, allowing the program to Prepare the readable byte segment in the input buffer before preparing to read.

Selecting Input from a Serial PortWhile 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 (2) system call through the select. 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 from the serial. Port Selection Input Although simple programs can read the serial port or wait for serial port data to read serial ports, most programs are not as simple, sometimes need to handle input from multiple sources. Unix provides this capability through SELECT (2) system call. This system call allows you to get input / output or error messages from one or more file descriptors. The file descriptor can point to the serial port, normal file, other devices, pipes, or sockets. You can query the input to be processed, wait for an unseasive input, or to complete the timeout after a designated timeout, these make the SELECT system call very flexible. Most GUI tools offer an excuse to point to SELECT, we will discuss the X Intrinsics library ("XT") in the following parts of this chapter.

The SELECT System CallThe 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 de Scriptors That Have a Pending Condition, or -1 if there is the an error.select system call Select system call can accept 5 parameters: int SELECT (int MAX_FD, FD_SET * INPUT, FD_SET * OUTPUT, FD_SET * Error, Struct TimeVal * Timeout The parameter MAX_FD defines the maximum value in all file descriptors (INPUT, OUTPUT, ERROR collections). Parameters INPUT, OUTPUT, Error defines the input, output, error condition to be processed; set NULL, representing the corresponding conditions. These collections use three macro to initialize fd_zero (fd_set); fd_set (fd, fd_set); fd_clr (fd, fd_set); macro FD_ZERO empty the entire collection; FD_SET and FD_CLR are added from the collection, delete file descriptors. The parameter TIMEOUT defines a timeout value composed of second (timeout.tv_sec) and milliseuit (timeout.tv_usec). To query one or more file descriptors, set second and milliseconds to 0. If you want to wait, you will put the Timeout point to the NULL. The SELECT system call returns the value of the file descriptor to be processed, or if there is an error, it returns -1.

Using the SELECT System CallSuppose 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. Using the SELECT system call assumes that we are reading data from a serial port and a socket. We want to confirm the input from each document descriptor, and hope that if there is no data in 10 seconds to notify the user. To complete these work, we can use the SELECT system call like a list 8:

Listing 8 - Using SELECT TO Process Input from More Than Ooney. List 8 - Use SELECT to process input from multiple sources #include #include #include #include #include #include #include #include int n; int socket; int fd; int max_fd; fd_set infut; struct timeval timeout; / * Initialize the input set initialization input collection * / fd_zero (input); fd_set (fd, input) ); Fd_set (socket, INPUT); max_fd = (socket> fd? Socket: fd) 1; / * Initialize the timeout structure initialization Timeout structure * / timeout.tv_usec = 10; timeout.tv_usec = 0; / * DO THE SELECT * / N = SELECT (max_fd, & infut, null, null, & timeout); / * see if there is an error checks if there is an error occurrence * / if (n <0) PERROR ("SELECT FAILED"); Else IF (n == 0) PUTS ("timeout"); Else {/ * We Have INPUT has input to * / if (fd_isset (fd, input) process_fd (); if (fd_isset, 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. You will find that we first check the return value called the SELECT system call. If 0 and -1 indicate the corresponding warnings and error messages. The value greater than 0 represents the data to be processed on the one or more file descriptors. To know which file descriptor is to be processed, we want to use the fdisset macro to test the input collection of each file descriptor. If the file descriptor flag is set, it meets the conditions (at this time, the input to be processed) we need to do some operations.

Using SELECT with the X Intrinsics LibraryThe 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 (eg 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).

转载请注明原文地址:https://www.9cbs.com/read-114097.html

New Post(0)