[comp.sys.hp] Need help setting up RS-232 port

markk@weycord.WEYCO.COM (Mark Kovach) (05/31/89)

Mark A. Kovach
weycord!markk
Weyerhaeuser Paper Co.
(206) 924-6142

I have what is probably a simple question but have not been
able to find a simple answer to it.  I have an HP9000/370 with
the HP-UX 6.5 operating system.  I simply need to open an
RS-232 port and send/receive ASCII data.  Nothing complicated. I'm
just going to use the port to talk with an analog mux.  I've got the
RS-232 expander cards to do the job on the system.  I just need to 
figure out how to do the job from a software standpoint.  Any assistance
would be welcome.  Thanks in advance.

pej@hpfinote.HP.COM (Phil Jensen) (06/03/89)

> I have what is probably a simple question but have not been
> able to find a simple answer to it.  I have an HP9000/370 with
> the HP-UX 6.5 operating system.  I simply need to open an
> RS-232 port and send/receive ASCII data.  Nothing complicated. I'm
> just going to use the port to talk with an analog mux.  I've got the
> RS-232 expander cards to do the job on the system.  I just need to 
> figure out how to do the job from a software standpoint.  Any assistance
> would be welcome.  Thanks in advance.
----------

The following should do what you need . Hope it helps .

*************************************************************************

#include <stdio.h>
#include <fcntl.h>
#include <termio.h>

#define BUFFER_SIZE 256
extern	int	errno;

main()
{
	int		tty;
	unsigned char 	buffer[BUFFER_SIZE];
	struct termio   term;

	/* open device as read / write 	 see mknod to make /dev/tty 	*/
	/* mknod /dev/tty c 1 0xscpp04 					*/
	/*       sc = select code      					*/
	/*       pp = port number for mux (98642) 00 for others   	*/

	if((tty = open("/dev/tty",O_RDWR)) < 1){
		fprintf(stderr,"Could not open /dev/tty ERRNO: %d\n",errno);
		exit(1);
	   }


	/* set up appropriate values for baud rate etc 			*/
	/* execute "man termio" for details 				*/

	term.c_oflag = OPOST;
	term.c_iflag = IGNBRK;
	term.c_lflag = 0;
	term.c_cflag = B2400|CSIZE|CS8|CREAD|CLOCAL;
	if(ioctl(tty,TCSETA,&term) == -1) {
		fprintf(stderr,"could not set /dev/tty\n");
		close(tty);
		exit(0);
	   }


	/* get BUFFER_SIZE bytes in character(byte) buffer 		*/

	read(tty,buffer,BUFFER_SIZE);


	/* write buffer to device 					*/

	write(tty,buffer,BUFFER_SIZE);

	
	/* close device 						*/

	close(tty);
}

guy@auspex.auspex.com (Guy Harris) (06/06/89)

>	/* open device as read / write 	 see mknod to make /dev/tty 	*/
>	/* mknod /dev/tty c 1 0xscpp04 					*/


Err, umm, unless HP-UX is a REALLY ALIEN life form (and, as far as I
know, it's not), you really DON'T want to do this.  "/dev/tty" is
supposed to be the "get me the controlling terminal" device in UNIX, and
should already exist on your machine; it should NOT refer to some
particular serial port. 

If you really meant "/dev/tty<something_or_other>", e.g.  "/dev/tty04"
or whatever, shouldn't that already exist once you've installed your
system?

rdg@hpfcmgw.HP.COM (Rob Gardner) (06/06/89)

> The following should do what you need . Hope it helps .
> 
> 	/* open device as read / write 	 see mknod to make /dev/tty 	*/
> 	/* mknod /dev/tty c 1 0xscpp04 					*/
> 
> 	if((tty = open("/dev/tty",O_RDWR)) < 1){
> 		fprintf(stderr,"Could not open /dev/tty ERRNO: %d\n",errno);

Whoa. Stop. Hold it right there. Don't do any mknod's like this on
/dev/tty or you will suffer very strange system behavior. Call the device
something like /dev/tty02. (/dev/tty is a special device, not a serial port.)

> 	term.c_oflag = OPOST;

You don't need OPOST if there are no other oflag bits set.

> 	term.c_iflag = IGNBRK;
> 	term.c_lflag = 0;
> 	term.c_cflag = B2400|CSIZE|CS8|CREAD|CLOCAL;

CSIZE is a mask used to find out what the character size is, so you don't
need it here. Since you created the tty device with "direct connect"
mode (that digit 4 at the end of the minor number), CLOCAL will have
no effect. See modem(7) for a very detailed description of this bit.

I would also recommend setting term.c_cc[VMIN] to 1 if you want to
be able to read 1 character at a time, otherwise you get whatever
junk happens to be in an uninitialized variable. (And this will be
the minimum number of characters that have to be read before the read()
call completes.)

> 	/* get BUFFER_SIZE bytes in character(byte) buffer 		*/
> 	read(tty,buffer,BUFFER_SIZE);
> 	/* write buffer to device 					*/
> 	write(tty,buffer,BUFFER_SIZE);

I would check the return value from the read() call, and use it in the
write call:

	ret = read(tty, buffer, BUFFER_SIZE);
	if (ret > 0)
		if (write(tty, buffer, ret) != ret)
			perror("....");
	etc, etc.

The reason is that in 'raw' mode (ie, ICANON is not set), the read
may complete before BUFFER_SIZE characters are read.


 
    Rob Gardner                     hplabs!hpfcmr!rdg
    Hewlett Packard                 or rdg%hpfcmr@hplabs.hp.com
    Fort Collins, Colorado          303-229-2048
		80525-9599

		     "Ask me about Home Brewing"

rdg@hpfcmgw.HP.COM (Rob Gardner) (06/07/89)

> >	/* open device as read / write 	 see mknod to make /dev/tty 	*/
> >	/* mknod /dev/tty c 1 0xscpp04 					*/

> Err, umm, unless HP-UX is a REALLY ALIEN life form (and, as far as I

It isn't.

> If you really meant "/dev/tty<something_or_other>", e.g.  "/dev/tty04"
> or whatever, shouldn't that already exist once you've installed your
> system?

Device files for ttys do not necessarily exist after an install.

Rob