Previous Next Contents

6. Hardware notes

6.1 How to make a cable

This section is just from messages I've seen on the net. I haven't done it so I can't write from experience. If anyone has, please write this section for me :). See also the message about the GPS1000 contained in section GPS1000 from ACCODATA, not to mention all the UPS specific data in section Info on selected UPSs.

   >From miquels@caution.cistron.nl.mugnet.org Wed Jul 21 14:26:33 1993
   Newsgroups: comp.os.linux
   Subject: Re: UPS interface for Linux?
   From: miquels@caution.cistron.nl.mugnet.org (Miquel van Smoorenburg)
   Date: Sat, 17 Jul 93 18:03:37
   Distribution: world
   Organization: Cistron Electronics.

   In article <1993Jul15.184450.5193@excaliber.uucp>
   joel@rac1.wam.umd.edu (Joel M. Hoffman) writes:
   >I'm in the process of buying a UPS (Uninteruptable Power Supply), and
   >notice that some of them have interfaces for LAN's to signal the LAN
   >when the power fails.
   >
   >Is there such an interface for Linux?
   >
   >Thanks.
   >
   >-Joel
   >(joel@wam.umd.edu)
   >

   When I worked on the last versioon of SysVinit (Now version 2.4),
   I temporarily had a UPS on my computer, so I added support for it.
   You might have seen that in the latest <signal.h> header files there
   is a #define SIGPWR 30 now :-). Anyway, I did not have such a special
   interface but the output of most UPS's is just a relais that makes or breaks
   on power interrupt. I thought up a simple way to connect this to the
   DCD line of the serial port. In the SysVinit package there is a daemon
   called 'powerd' that keeps an eye on that serial line and sends SIGPWR
   to init when the status changes, so that init can do something (such as
   bringing the system down within 5 minutes). How to connect the UPS to
   the serial line is described in the source "powerd.c", but I will
   draw it here for explanation:

                        +------------------------o  DTR
                        |
                      +---+
                      |   | resistor
                      |   | 10 kilo-Ohm
                      |   |
                      +---+                                To serial port.
                        |
          +-----o-------+------------------------o  DCD
          |             |
          o  UPS        |
        \    relais     |
         \              |
          |             |
          +-----o-------+------------------------o  GND

   Nice drawing eh?

   Hope this helps.
   SysVinit can be found on sunsite (and tsx-11 probably) as
   SysVinit2.4.tar.z

   Mike.

   --

   Miquel van Smoorenburg, <miquels@cistron.nl.mugnet.org>
   Ibmio.com: cannot open CONFIG.SYS: file handle broke off.


   >From danny@caution.cistron.nl.mugnet.org Wed Jul 21 14:27:04 1993
   Newsgroups: comp.os.linux
   Subject: Re: UPS interface for Linux?
   From: danny@caution.cistron.nl.mugnet.org (Danny ter Haar)
   Date: Mon, 19 Jul 93 11:02:14
   Distribution: world
   Organization: Cistron Electronics.

   In article <9307174330@caution.cistron.nl.mugnet.org>
   miquels@caution.cistron.nl.mugnet.org (Miquel van Smoorenburg) writes:
   >How to connect the UPS to the serial line is described in the source
   >"powerd.c", but I will draw it here for explanation:

   The drawing wasn't really clear, please use this one in stead !
   >
   >                     +------------------------o  DTR
   >                     |
   >                   +---+
   >                   |   | resistor
   >                   |   | 10 kilo-Ohm
   >                   |   |
   >                   +---+                                To serial port.
   >                     |
   >       +-----o-------+------------------------o  DCD
   >       |
   >       o  UPS
   >     \    relais
   >      \
   >       |
   >       +-----o--------------------------------o  GND
   >

   The DTR is kept high, when the UPS's power input is gone it
   will close the relais . The computer is monitoring
   the DCD input port to go LOW . When this happens it will start a
   shutdown sequence...

   _____
   Danny

   --
   <=====================================================================>
   Danny ter Haar  <dannyth@hacktic.nl> or <danny@cistron.nl.mugnet.org>
   Robins law #103: 'a couple of lightyears can't part good friends'

6.2 Reverse-engineering cables and hacking powerd.c

Try to get documentation for the cables that your UPS seller supplies. In particular find out:

You then need to either hack powerd.c appropriately, or use one of the above configurable packages (see the packages genpower-1.0.1.tgz, powerd-2.0.tar.gz, or upsd-1.0.tgz described in section Software). If you use one of the packages, follow the instructions there. If you want to hack powerd.c, keep reading.

If you have trouble getting the above information, or just want to check it (a good idea) the following program might help. It's a hacked version of powerd.c. It allows you to set the necessary port flags from the command line and then monitors the port, displaying the control lines every second. I used it as ``upscheck /dev/cua1 2'' (for example) to set the 2nd bit (DTR) and to clear the other bits. The number base 2 indicates which bits to set, so for example to set bits 1, 2 and 3, (and clear the others) use 7. See the code for details.

Here's the (untested) upscheck.c program. It's untested because I edited the version I originally used to make it clearer, and can't test the new version at the moment.

/*
 * upscheck     Check how UPS & computer communicate.
 *
 * Usage:       upscheck <device> <bits to set>
 *              For example, upscheck /dev/cua4 4 to set bit 3 &
 *              monitor /dev/cua4.
 *
 * Author:      Harvey J. Stein <hjstein@math.huji.ac.il>
 *              (but really just a minor modification of Miquel van
 *              Smoorenburg's <miquels@drinkel.nl.mugnet.org> powerd.c
 *
 * Version:     1.0 19940802
 *
 */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>

/* Main program. */
int main(int argc, char **argv)
{
  int fd;

/*  These TIOCM_* parameters are defined in <linux/termios.h>, which  */
/*  is indirectly included here.                                      */
  int dtr_bit = TIOCM_DTR;
  int rts_bit = TIOCM_RTS;
  int set_bits;
  int flags;
  int status, oldstat = -1;
  int count = 0;
  int pc;

  if (argc < 2) {
        fprintf(stderr, "Usage: upscheck <device> <bits-to-set>\n");
        exit(1);
  }

  /* Open monitor device. */
  if ((fd = open(argv[1], O_RDWR | O_NDELAY)) < 0) {
    fprintf(stderr, "upscheck: %s: %s\n", argv[1], sys_errlist[errno]);
    exit(1);}

  /* Get the bits to set from the command line. */
  sscanf(argv[2], "%d", &set_bits);

  while (1) {
    /* Set the command line specified bits (& only the command line */
    /* specified bits).                                             */
    ioctl(fd, TIOCMSET, &set_bits);
    fprintf(stderr, "Setting %o.\n", set_bits);

    sleep(1);

    /* Get the current line bits */
    ioctl(fd, TIOCMGET, &flags);
    fprintf(stderr, "Flags are %o.\n", flags);

/*  Fiddle here by changing TIOCM_CTS to some other TIOCM until    */
/*  this program detects that the power goes out when you yank     */
/*  the plug on the UPS.  Then you'll know how to modify powerd.c. */
    if (flags & TIOCM_CTS) 
      {
        pc = 0 ;
        fprintf(stderr, "power is up.\n");
      }
    else 
      { 
        pc = pc + 1 ; 
        fprintf(stderr, "power is down.\n");
      }
    }

  close(fd);
}

6.3 Serial port pin assignments

The previous section presupposes knowledge of the correspondence between terminal signals and serial port pins. Here's a reference for that correspondence, taken from David Tal's ``Frequently Used Cables and Connectors'' document. I'm including a diagram illustrating the connectors, and a table listing the correspondence between pin numbers and terminal line signals.

If you need a general reference for cable wiring, connectors, etc, then David Tal's would be a good one, but I can't seem to locate this document on the net any more. But I've found a good replacement. It's The Hardware Book.

Other useful sites:

Incidentally, it seems that the Linuxdoc-sgml package still doesn't format tables very well in the html output. If you want to be able to read the following table, you're probably going to have to look at either the DVI version or the plain text version of this document.


DB-25 DB-9 Name EIA CCITT DTE-DCE Description
Pin # Pin #

1 FG AA 101 --- Frame Ground/Chassis GND
2 3 TD BA 103 ---> Transmitted Data, TxD
3 2 RD BB 104 <--- Received Data, RxD
4 7 RTS CA 105 ---> Request To Send
5 8 CTS CB 106 <--- Clear To Send
6 6 DSR CC 107 <--- Data Set Ready
7 5 SG AB 102 ---- Signal Ground, GND
8 1 DCD CF 109 <--- Data Carrier Detect
9 -- -- - - Positive DC test voltage
10 -- -- - - Negative DC test voltage
11 QM -- - <--- Equalizer mode
12 SDCD SCF 122 <--- Secondary Data Carrier Detect
13 SCTS SCB 121 <--- Secondary Clear To Send
14 STD SBA 118 ---> Secondary Transmitted Data
15 TC DB 114 <--- Transmitter (signal) Clock
16 SRD SBB 119 <--- Secondary Receiver Clock
17 RC DD 115 ---> Receiver (signal) Clock
18 DCR -- - <--- Divided Clock Receiver
19 SRTS SCA 120 ---> Secondary Request To Send
20 4 DTR CD 108.2 ---> Data Terminal Ready
21 SQ CG 110 <--- Signal Quality Detect
22 9 RI CE 125 <--- Ring Indicator
23 -- CH 111 ---> Data rate selector
24 -- CI 112 <--- Data rate selector
25 TC DA 113 <--- Transmitted Clock
Pin Assignment for the Serial Port (RS-232C), 25-pin and 9-pin

        1                         13         1         5
      _______________________________      _______________
      \  . . . . . . . . . . . . .  /      \  . . . . .  /    RS232-connectors
       \  . . . . . . . . . . . .  /        \  . . . .  /     seen from outside
        ---------------------------          -----------      of computer.
        14                      25            6       9

   DTE : Data Terminal Equipment (i.e. computer)
   DCE : Data Communications Equipment (i.e. modem)
   RxD : Data received; 1 is transmitted "low", 0 as "high"
   TxD : Data sent; 1 is transmitted "low", 0 as "high"
   DTR : DTE announces that it is powered up and ready to communicate
   DSR : DCE announces that it is ready to communicate; low=modem hangup
   RTS : DTE asks DCE for permission to send data
   CTS : DCE agrees on RTS
   RI  : DCE signals the DTE that an establishment of a connection is attempted
   DCD : DCE announces that a connection is established

6.4 Ioctl to RS232 correspondence

Since you also might need to modify powerd.c to raise and lower the correct lines, you might also need the numeric values of different terminal signals. The can be found in /usr/include/linux/termios.h, but are reproduced here for reference. Since they could change, you're best off confirming these values against said file.

/* modem lines */
#define TIOCM_LE        0x001
#define TIOCM_DTR       0x002
#define TIOCM_RTS       0x004
#define TIOCM_ST        0x008
#define TIOCM_SR        0x010
#define TIOCM_CTS       0x020
#define TIOCM_CAR       0x040
#define TIOCM_RNG       0x080
#define TIOCM_DSR       0x100
#define TIOCM_CD        TIOCM_CAR
#define TIOCM_RI        TIOCM_RNG

Note that the 3rd column is in Hex.


Previous Next Contents