HPlogo Asynchronous Serial Communications Programmer's Reference Manual: HP 3000 MPE/iX Computer Systems > Chapter 3 Common Device Control Functions

Reading From Asynchronous Devices

» 

Technical documentation

Complete book in PDF
» Feedback

 » Table of Contents

 » Glossary

 » Index

Data is read from a terminal by means of the FREAD, READ or READX intrinsic. FREAD is the most versatile of the three, but requires the use of a file number. READ allows reading from $STDIN only; READX allows reading from $STDINX only. Neither READ nor READX requires the use of a file number, but their utility is somewhat limited.

The manner in which a read from a terminal device takes place is determined by the device control settings in effect for that device at the time the read is issued. You can modify many of these settings by using specific device control intrinsics prior to issuing a read.

The following paragraphs summarize the settings that are relevant when reading input from a terminal device and the effect these settings have on how a read will occur. See Chapter 8 “Intrinsics Reference” of this manual for details on using specific device control intrinsics.

Input Modes

When devices are connected asynchronously, data is always sent one character at a time. The transmission of data may occur in either character mode or block mode, depending on the physical settings of the device and the settings of the ASC software controlling the device.

Character Mode

Under default conditions, transmission of data occurs in character mode, with characters transmitted to the DTC individually as they are typed in. When the read is terminated, the DTC transmits the accumulated data to the host. If DTC echo is enabled, characters are echoed back to the terminal screen as they are received. Under default conditions, character mode reads are terminated by a carriage return. Character mode is available with all supported terminal types and is the mode in which all terminals are opened, whether by a session or a program.

Block Mode

When a terminal is operating in block mode, characters are held in the terminal's internal memory (buffer) as they are typed in. They are not transmitted to the DTC until after you have taken a specific action (normally, pressing the [Enter] key).

Data transmission may occur a line at a time (line block mode) or a page at a time (page block mode) depending on the settings of the terminal and the type of block mode being used.

Block mode is enabled programmatically by a block mode application when it is executed at a terminal. The terminal's configuration settings need to be changed also, in order for the terminal to function properly in block mode. This can be done by prompting the user to change the terminal's configuration settings or by programmatically sending escape sequences to the terminal.

Block mode allows a terminal user to see data on the screen as it is being typed in and to use the terminal's local editing and cursor control features to alter the data before it is transmitted to the DTC. It is available only on terminals that have block mode capabilities; all of the terminals supported for use on MPE/iX systems are capable of handling block mode data transmission. When using a PC, however, you should verify that the terminal emulation program you are using is capable of handling block mode transmission.

User block mode can be invoked through a call to FCONTROL(29) and makes it possible for your program to control the way in which a block mode transaction will take place. See the discussion of FCONTROL(28,29) in chapter 8 for more information on user block mode.

NOTE: A convenient way to handle block mode processing is provided by the VPLUS intrinsics.VPLUS intrinsics automatically perform many of the block mode terminal control operations that you are otherwise responsible for. It is recommended that you use this method whenever possible. See the VPLUS Reference Manual for more information on using the VPLUS intrinsics.

Field Mode

Enhancements have been added to provide the performance of block mode and the flexibility of character mode, called field mode.

Field mode was created to help application programmers control certain keys on the keyboard. Some applications require certain keys to be controlled by the application and not processed locally in the terminal. Block mode applications do not recognize any of these special keys except in some cases where they are processed locally by the terminal. To process the special characters would require reading characters one at a time. This would result in performance degradation.

Field mode allows the users to collect normal user data input without having to interrupt the CPU for each character, yet still have many ways to return control to the application when the user enters command input. The basic building blocks for field mode are summarized:

  • Inter-byte timer. Provides a mechanism by which the DTC can terminate a read and forward data to the host. It is useful for collecting data where there is no guarantee that an end-of-record or alternative end-of-record character will be received, or that a specified number of bytes will be received. It is implemented in FDEVICECONTROL 192, parm1 = 65.

  • Multiple alternative end-of-record (AEOR) characters. Allows an application or user to specify up to 16 AEOR characters. When the DTC receives one of these characters, it completes the current pending read request with the received AEOR character as the last byte of data. This functionality is implemented in FDEVICECONTROL 192, parm1 = 66.

    It is also implemented in TTUTIL.PUB.SYS, in the Special Characters Screen. Refer to the Customizing Terminal and Printer Type Files Using the Workstation Configurator manual for more information on TTUTIL.

  • Delete to backspace mapping. Allows the delete character (the [DEL] key) to be processed as a backspace character, in order to support ANSI mode terminals. These terminals send the delete character when the backspace key is pressed. This is implemented in FDEVICECONTROL 192, parm1 = 67.

  • Escape sequence read termination. Enables an application to have a read terminated by an ESC sequence and receive the entire ESC sequence in the data. It is implemented in FDEVICECONTROL 192, parm1 = 68. An application cannot enable both the escape sequence read termination and the inter-byte timer method.

  • Suppress echo of read termination character. Allows applications to determine whether or not to include the read terminators with the data that is echoed back to the device. It is implemented in FDEVICECONTROL 192, parm1 = 69.

Refer to FDEVICECONTROL in Chapter 8 “Intrinsics Reference” for more information on these functionalities.

Data Editing Modes

When data is entered from a terminal, a number of control characters, referred to as special characters, signal the DTC or the ASC software to perform specific functions. The functions vary from deleting a character from the input stream to interrupting a program or subsystem. All special characters are stripped from the data after the system (or the DTC) responds to them. The specific characters that will be treated as special characters vary depending on the data editing mode being employed. Standard editing, transparent editing, and binary editing modes are available.

Standard Mode

Standard editing mode is enabled by default for asynchronous terminals. All special characters recognized by MPE/iX are available in standard editing mode. See Configuring Systems for Terminals, Printers and Other Serial Devices for a complete description of all the standard special characters.

Transparent Mode

In transparent editing mode, only a limited number of special characters retain their meanings and are acted on by the system. Also referred to as unedited mode, this facility allows many of the characters that would otherwise be treated as special characters to be passed through as input, without causing any control action to be performed or being stripped from the input data stream. Table 8-6 “Special Characters for Transparent Editing” lists the special characters that retain their meaning in transparent mode. FCONTROL(41) can be used to enable transparent mode. The FDEVICECONTROL intrinsic can also be used to enable transparent editing mode. You will find examples of invoking transparent editing mode later in this chapter and in Chapter 4 “Using FDEVICECONTROL”

Binary Mode

In binary editing mode no special characters are recognized. All characters are treated as data and passed through without any terminal control actions being taken. Only character mode processing is possible in binary mode, since there are no special characters available to control block mode processing. Any carriage control information contained in output data transmitted in binary mode will be stripped. Use FCONTROL(26,27) to enable and disable binary mode transfers.

Triggering Reads

With some exceptions, every time a read is issued on an asynchronous device a read trigger character is sent to the device, indicating that the system is ready to receive input. The read trigger is not transmitted over PAD connections and may not be issued if typeahead mode is enabled at a terminal and the typeahead feature is being used.

The normal read trigger character is the ASCII DC1 character (the same as XON). All terminal devices supported for use on HP 3000 Series 900 computers are capable of recognizing and responding to the DC1 read trigger character.

The read trigger is generated at the beginning of each read and signals that the system is ready to receive data. If the device is operating in character mode, the device can begin transmitting without any further exchange of protocol characters. If, however, the data is to be sent through block mode, the device must inform the DTC by sending an ASCII DC2 character in response to the read trigger. The DTC, now informed that the data will be transmitted as a block, sends another read trigger when it is ready to accept the block of data. The second read trigger is referred to as a block mode read trigger and is the same character as the read trigger.

It is possible to specify an alternate character for use as the read trigger (and therefore also the block mode read trigger) through the FDEVICECONTROL intrinsic. You must take great care if you do so, however, to assure that no data is lost.

Terminating Reads

Reads can be terminated in a number of ways, depending on the programmatic controls issued by your program prior to posting the read. Both the input mode (character or block mode) and the data editing mode (binary, transparent, or standard editing mode) affect the termination of reads.

Binary mode reads cannot be terminated by the recognition of any character. Binary mode reads are terminated only by the byte count being reached or by the expiration of the read limit timer. Only byte count termination results in a successful binary mode read.

The following summarizes the events that will cause reads other than binary mode reads to terminate

  • An EOR character is sent from the terminal. This includes the block mode read termination character (usually RS) if you are in block mode and any EOR character specified in an FCONTROL(41) call or through FDEVICECONTROL(192) with a controlcode value of 15 or 39. Reads terminated in this way terminate normally.

  • An AEOR character defined in a preceding call to FCONTROL(25) is sent from the terminal. The AEOR character is included in the data and the byte count and the read terminates with an error condition (FSERR 31). An AEOR character will be recognized in either standard or transparent editing mode.

  • The input byte count is reached. This count is set by a parameter in the read intrinsic used for the read (FREAD, READ, or READX). Reaching the input byte count causes all reads to terminate, regardless of any other condition.

  • The read limit timer set by a preceding call to FCONTROL(4) expires. Setting this timeout value prevents a device from hanging because of an incomplete read. The read data is transferred to the user buffer and the read length is returned. The length is the number of characters entered at the time of the timeout, and the read terminates with SOFTWARE TIMEOUT (FSERR 22). Reaching the timeout limit causes all reads to terminate, regardless of any other condition. (During block mode reads, the timer halts when the DC2 character is received.)

  • In block mode, the block mode read timer expires. This timer is active from the time that the second DC1 is sent until the RS character is received. The timer expires with a VPLUS intrinsic error if VPLUS block mode is being used. The timer expires with a file system error (FSERR 27) if any other type of block mode is being used.

  • System break is sent from the terminal (and system break is not disabled). All read data is lost, but the read is reposted when the user resumes the application.

  • The subsystem break character is sent from the terminal while subsystem break is enabled. All read data is returned to the sender. Subsystem break is not recognized in binary mode.

  • The DTC encounters a parity error while parity is enabled. Parity is not recognized in binary mode.

End of File Indicators

If a program is reading from one of the standard input files, certain conditions will cause an end-of-file to occur and the read will terminate with a condition code of CCG (>>). On $STDIN an end-of-file occurs if a colon (:) is encountered in column 1 of the record being read. On $STDINX the end-of-file occurs only if the first four characters of the record are :EOF. Once your program encounters an end-of-file condition on a standard file, any subsequent read requests issued by the program against the same file will also encounter an end-of-file. For this reason, your program should check for the end-of-file condition as the first step in reading input from a device. If one is found, the current file must be closed, because a read will not succeed.

Using FREAD

Once your program has successfully opened a file on a terminal device, with read access specified, and a valid file number is obtained as a result of the file open call, you can use the FREAD intrinsic to read data from the device. Make sure to issue any calls to affect the way the read will take place (input mode, data editing mode, etc.) before posting the read. The syntax of the FREAD call is as follows:

     I16		                   I16V	     UDS      	I16V
transfercount:=FREAD(filenum,buffer,length);

FREAD accesses the devicefile through its file number (filenum) and the data input from the device is transferred to buffer when one of the read termination conditions occurs.

The byte count is specified in the length parameter of the FREAD call. The intrinsic allows you to specify length as either a positive value representing halfwords or a negative value representing bytes. However, for asynchronous devices, the actual data transfer always occurs on a byte-by-byte basis. If the number of bytes input reaches the value specified, the read will terminate on byte count.

For asynchronous terminals, the maximum supported read length is four kilobytes (4 KB) in standard or transparent editing mode and 128 bytes in binary editing mode.

If transfercount is used, the actual number of bytes transferred as a result of the read will be returned as its value. If you specified NOWAIT I/O in the FOPEN or HPFOPEN call, however, this value will be 0 and the actual byte count will be returned in the IOWAIT or IODONTWAIT call. See Chapter 8 “Intrinsics Reference” of this manual for more information on IOWAIT and IODONTWAIT.

The program fragment shown in Figure 3-2 “Illustration of the FREAD Intrinsic” illustrates the use of the FREAD intrinsic. NOWAIT I/O is not used in this example. A file is opened as $STDIN with 80 byte ASCII records specified and the file number is returned in the fileid_in variable. A read is then posted against this file using the FREAD intrinsic to read up to 80 bytes and store the data as the value of read_buffer. Note that read_buffer is declared as a string large enough to hold up to the maximum amount of data that could be transferred in a single FREAD call.

Figure 3-2 Illustration of the FREAD Intrinsic

Illustration of the FREAD Intrinsic

Timing a Read

On MPE/iX systems every read that occurs is timed; there is never a need to turn a timer on to obtain information about the length of a read. However, the result of the timer is not actually returned to your program unless you explicitly issue an FCONTROL call, using 22 as the value of the controlcode parameter. This FCONTROL call returns the time used for the immediately preceding read as the value of param.

The time of the read is returned in hundredths of a second, up to a limit of 655.35 seconds. This limit is imposed by the 16-bit capacity of param. If the read being timed took longer than 655.35 seconds to complete, the FCONTROL call returns a CCG condition. A call to FCHECK would return an FSERR 98, Read Timer Overflow.

The code fragment shown in Figure 3-3 “Obtaining the Result of the Read Timer” posts a read against fileid_in and issues a call to FCONTROL(22) immediately after the read to obtain the results of the read timer. After execution of the FCONTROL call, read_time will contain the results of the timer and the program will write this value to the standard output device. The code sample also checks for a CCE condition, which would indicate that the FCONTROL had succeeded.

Figure 3-3 Obtaining the Result of the Read Timer

Obtaining the Result of the Read Timer

Setting a Read Time Limit

FCONTROL can also be used to set a time limit on a succeeding read, by specifying 4 as the value of controlcode and specifying a time limit, in seconds, through param (up to 65535 seconds). If the read immediately following the call takes more than the time specified, the read will terminate in error and any data already received will be flushed. The read limit remains in effect only for the next read. You must issue a separate FCONTROL(4) call prior to every read on which you want to impose a time limit.

There are many circumstances in which it is advisable to set a timeout value. Timeouts should always be used with devices that operate without a dedicated attendant, to prevent hangs that could occur if the device were to fail in some way.

Timeouts are effective in all data editing modes. This makes it possible to terminate even a binary mode read should it exceed the specified time limit. During block mode reads, however, the timer is halted upon receipt of the DC2 character and the block mode read timer takes over.

When a read terminates as the result of exceeding the timeout set by FCONTROL(4), the read fails with a CCL condition and all data is lost. A call to FCHECK returns an FSERR 22, Software Timeout.

The code segment shown in Figure 3-4 “Opening a Read Port and a Write Port” sets a 30-second time limit for the next read posted against fileid_in. The sample includes an error checking routine which verifies whether or not the read terminated normally. If not, the program calls FCHECK. If FCHECK returns an FSERR 22, the program will inform the user that a read timeout occurred.

Figure 3-4 Opening a Read Port and a Write Port

Opening a Read Port and a Write Port

Using READ or READX

The READ and READX intrinsics provide a simple method for reading from the standard input device. You do not need to know the file number when you use these intrinsics. Except for the intrinsic name, the syntax is the same for READ and READX. The syntax of the READ intrinsic is shown below:

    I16              		CA		         I16V
transfercount:=READ(message,expectedlength);

The maximum length of the read is passed in expectedlength and the call returns the actual length of the read in transfercount, if transfercount is used. The read data is returned in message.

Both READ and READX transfer an ASCII string into a character array in your program. However, READ transfers data from $STDIN, while READX transfers data from $STDINX. READ also differs from READX in the way an end-of-file is interpreted. READ recognizes any colon (:) found in column 1 as an end-of-file, while READX interprets only :EOD as an end-of-file.

Because there is no file number associated with READ or READX, it is not possible to use the FCHECK intrinsic to determine what took place in the event of an error. Nor can you use the :FILE command to redirect input, since the input always comes from the standard input files opened by the session at logon time.

Because of the limitations inherent in the use of READ and READX, it is recommended that you use these intrinsics only for temporary programs as a quick way to obtain input from a terminal. A better programming practice for permanent programs would be to use FOPEN or HPFOPEN to open $STDIN or $STDINX and then issue FREAD calls against these files.

Feedback to webmaster