Hallo Code-Gurus,
das folgende Progrämmchen ist nicht von mir selbst. Es ist Bestandteil von diesem Archiv.
Erst mal zur Erklärung, was das Programm überhaupt macht:
Das Programm dient dazu, die DTR-Leitung einer seriellen Schnittstelle auf HIGH oder LOW zu setzen. Mittels dieser Leitung wird eine an die serielle Schnittstelle angeschlossene Relaiskarte gesteuert, an der Wiederum mein TFT angeschlossen ist.
Um es in Betrieb zu nehmen, muss zunächst die gewünschte serielle Schnittstelle verlinkt werden auf /dev/powerswitch, in meinem Fall ist dies /dev/ttyS1 (also COM2). Dann wird mittels "mkfifo -m 0666 /dev/powerctrl" ein FIFO angelegt, an den die Signale (0,1,T) gesendet werden können.
So weit so gut, wenn das Programm gestartet ist (powerswitch &), lässt sich mit "echo SIGNAL > /dev/powerctrl" die Relaiskarte schalten.
Leider verbraucht das Programm aber, nachdem es das erste Signal gelesen hat, 100% CPU.
Hier mal der Original-Code:
/*****************************************************************************\
* powerswitch - Kontrollprogramm für die serielle Schalt-Steckdose *
* Copyright (C) 2004 bei Mirko Dölle <mdoelle@linuxnewmedia.de> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation, *
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
\*****************************************************************************/
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
int serial = 0;
int terminal = 0;
char defaultserial[] = "/dev/powerswitch";
char defaultterminal[] = "/dev/powerctrl";
typedef enum
{
PAUS = 0, PEIN, PTOGGLE
} Schalten;
int SetPowerSwitch(Schalten Zustand, int fd, int* currstat)
{
if(Zustand == PEIN)
{
*currstat |= TIOCM_DTR;
ioctl(fd, TIOCMSET, currstat);
return 0;
}
if(Zustand == PAUS)
{
*currstat &= ~TIOCM_DTR;
ioctl(fd, TIOCMSET, currstat);
return 0;
}
if(Zustand == PTOGGLE)
{
*currstat ^= TIOCM_DTR;
ioctl(fd, TIOCMSET, currstat);
return 0;
}
return 1;
}
void Cleanup(int code)
{
int currstat = 0;
ioctl(serial, TIOCMSET, &currstat);
close(serial);
fcntl(terminal, F_SETFL, 0);
close(terminal);
exit(0);
}
int main(int argc, char** argv)
{
fd_set rfds;
int retval;
int currstat;
int buffer;
char* serdev;
char* termdev;
/* Parameterprüfung: Das zu verwendende Device muß als erster Parameter */
/* angegeben werden. */
switch (argc)
{
case 3:
serdev = argv[1];
termdev = argv[2];
break;
case 2:
serdev = argv[1];
termdev = defaultterminal;
break;
case 1:
serdev = defaultserial;
termdev = defaultterminal;
break;
default:
printf("Fehler: Ungültige Parameter-Anzahl.\n");
printf("Aufruf:\n");
printf(" powerswitch <Seriell> <Terminal>\n");
exit(-1);
}
/* Signale INT und TERM abfangen, erst Panel auf rot setzen dann exit */
signal (SIGINT, Cleanup);
signal (SIGTERM, Cleanup);
/* Serielle Schnittstelle öffnen */
if((serial = open(serdev, O_RDWR | O_NDELAY)) < 0)
{
printf("Fehler: Device \"%s\" kann nicht geöffnet werden.\n", serdev);
exit(-1);
}
else
{
/* Schnittstelle initialisieren: Alle Status-Leitungen abschalten */
currstat = 0;
ioctl(serial, TIOCMSET, &currstat);
}
if((terminal = open(termdev, O_NDELAY)) < 0)
{
printf("Fehler: Device \"%s\" kann nicht geöffnet werden.\n", termdev);
exit(-1);
}
while (1)
{
FD_ZERO(&rfds);
FD_SET(terminal, &rfds);
retval = select(terminal+1, &rfds, NULL, NULL, NULL);
if((retval) && (errno == 0))
{
if((FD_ISSET(terminal, &rfds)) &&
(read(terminal, &buffer, sizeof(char) == 1)))
{
switch ((char) buffer)
{
case '1':
SetPowerSwitch(PEIN, serial, &currstat);
break;
case '0':
SetPowerSwitch(PAUS, serial, &currstat);
break;
case 't':
case 'T':
SetPowerSwitch(PTOGGLE, serial, &currstat);
break;
case 'q':
case 'Q':
Cleanup(0);
default:
;
}
}
}
}
return 0;
}
Alles anzeigen
Ich vermute mal, das Problem liegt irgendwo am Anfang der while(1)-Schleife (ist das Busy-Waiting?). Aber irgendwie steh ich grad auf dem Schlauch. Vielleicht sieht ja jemand eine einfache Lösung für das Problem mit 100% CPU.
Vielen Dank schonmal,
fitzefatze