Pro-Linux

Pro-Linux Diskussions- und Hilfeforum
Aktuelle Zeit: 13. Nov 2018 23:56

Alle Zeiten sind UTC+01:00




Ein neues Thema erstellen  Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Do while C++ und Linux
BeitragVerfasst: 23. Okt 2007 13:50 
Hallo,

ich bin neuer besutzer in diesem Forum und beschäftige mich nicht so lange mit Linux.
Ich habe ein Programm das für C++ geschrieben war in Linux umgeschrieben, nur scheint die Funktion einer do while Schleife anders zu sein. Die Schleife lässt sich garnicht starten.
Konkret geht es um folgende Schliefe, die als Anfangsbedingung den Wert !1 und als Stop- Wert den Wert !0 erhält. Tätsachlich lässt sich auch überprüfen dass sich diese Werte ändern nur lässt sich der Status der Schleife nicht beeinflussen. Die Werte werden aus dem Register eines Messinstrumentes mithilfe der Funktion ioctl ausgelesen.

do
{
i=0; res_ist=82.31045/1000;

while (!(ioctl(acam_fd16, 0x8)&0x0800))
{



{C3=ioctl(acam_fd16, 0x8)&0x0800; printf("FIFO empty? C3 %X\n",C3);}

ioctl(acam_fd16, WRITE_ACAM | 0x4, 0x0008);
FIFO0 = (ioctl(acam_fd16, 0x0)); //Read IFIFO1
Edge = (FIFO0>>17 & 0x00020000);
Chan = FIFO0>>26 & 0x00000001;
FIFO0 = FIFO0 & 0x0001ffff; {printf("FIFO0 %X\n" ,FIFO0);}
printf("ch %d hit# %d Edge %d \t%5.3fns\n\n ",Chan+1, i+1,Edge,(FIFO0)*82.31045/1000);
i++;
}

Die Äquivalenz zu boolschen Werten sind soweit ich weiss bei Linux ja True=1 und False=0, also sollte dies auch kein Problem machen.
Die Syntax zu ändern auf while (statement) do {expression} hilft auch nicht weiter. Hat jemand eine Idee was denn das Problem macht?
Danke

Euer Daniel


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 23. Okt 2007 16:30 
Offline
Benutzeravatar

Registriert: 11. Feb 2006 19:10
Beiträge: 3569
Ich ordne erstmal diesen Code.
Code:
do 
{ 
  i=0; res_ist=82.31045/1000; 
 
  while (!(ioctl(acam_fd16, 0x8)&0x0800)) 
  {
    {C3=ioctl(acam_fd16, 0x8)&0x0800; printf("FIFO empty? C3 %X\n",C3);}
 
    ioctl(acam_fd16, WRITE_ACAM | 0x4, 0x0008); 
    FIFO0 = (ioctl(acam_fd16, 0x0)); //Read IFIFO1 
    Edge = (FIFO0>>17 & 0x00020000); 
    Chan = FIFO0>>26 & 0x00000001; 
    FIFO0 = FIFO0 & 0x0001ffff; {printf("FIFO0 %X\n" ,FIFO0);} 
    printf("ch %d hit# %d Edge %d \t%5.3fns\n\n ",Chan+1, i+1,Edge,(FIFO0)*82.31045/1000); 

    i++;
  }
Zitat:
Hat jemand eine Idee was denn das Problem macht?
Ja.

1. Das gegebene Codestück ist so unvollständig, dass man es nicht nachvollziehen kann. Wo sind die ganzen Variablen definiert?
2. Kompilieren lässt sich das erst recht nicht.
3. Kommentare, was es angeblich machen *soll*, sind ebenfalls Mangelware.
4. Der Rückgabewert von ioctl ist negativ für den Fehlerfall, sonst 0 oder positiv. Du prüfst den Fehlerfall aber gar nicht getrennt von deinem Fall ab, dass das Bit 0x0800 gesetzt ist.
Im Fehlerfall kommt aus deinem ioctl() eine negative Zahl raus, das ist in der Bitdarstellung irgendwas wie 0xfffffffffe
Mit ioctl()&0x800 wird daraus eine Zahl !=0, also *wahr*. Das drehst du mit ! um, also wird der Block innerhalb des while nicht aufgerufen.

Klär das erstmal, bevor du darüber spekulierst, ob "Linux" vielleicht True=0 definiert (C tut es nicht, gcc/g++ tut es auch nicht, und Linux erst recht nicht).

Janka

_________________
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 24. Okt 2007 9:49 
Hallo,

entschuldigung, soweit ich es nachvollziehen konnte, gibt es kein Problem bei der Variablendefinition, darum habe ich den Rest auch weggelassen. Wie gesagt das Programm lässt sich ohne Problem komplieren, die Schliefe lässt sich aber nicht starten.Dass ich nach den hypothetischen Unterschied zwischen C++ und ANSI C (Linux) gefragt habe, ist weil die Schleife unter C++ in dieser Form gestartet werden kann.

Ich füge mal das wichtigste hinzu.

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <signal.h>
#include <math.h>
#include <stdbool.h>

#define acam_device16 "/dev/acam_gpx_16"
#define acam_device32 "/dev/acam_gpx_32"

int main(int argc, char * argv[])
{
int acam_fd32;int acam_fd16;
unsigned int FIFO0;
unsigned int FIFO;
unsigned int FIFO1;

{
do
{
i=0;

while (!(ioctl(acam_fd16, 0x8)&0x0800))//Lese die while Bedingung aus einem bestimmten Register
{


ioctl(acam_fd16, WRITE_ACAM | 0x4, 0x0008);
FIFO0 = (ioctl(acam_fd16, 0x0)); //Lese aus einem
bestimmten Register
Edge = (FIFO0>>17 & 0x00020000);
Chan = FIFO0>>26 & 0x00000001;
FIFO0 = FIFO0 & 0x0001ffff; {printf("FIFO0 %X\n" ,FIFO0);}
printf("ch %d hit# %d Edge %d \t%5.3fns\n\n ",Chan+1, i+1,Edge,(FIFO0)*82.31045/1000);

i++;
}
}
}


Die Funktion (ioctl(acam_fd16, 0x8)&0x0800) liefert einen Wert von 1, wenn die Schleife anfangen soll und 0 wenn sie beendet werden soll. Daher die Bedingung while(!1):Also falls nicht true, soll das Instrument ausgelesen werden. Daran liegt vielleicht auch das Problem, was ich mit meiner Frage noch nachgehen wollte.
Da while mit booleans arbeitet, wird, soweit ich weiss der Wert 1 als true aufgefasst und der Wert 0 als false, kann also bei nicht true nicht gestartet werden. Gibt es keine Form dies unter ANSI C zu umgehen?

Man kann auch die Bedingung
while ((ioctl(acam_fd16, 0x8)&0x0800)!=1)
schreiben. Unter dieser Bedingung wird die Schleife sogar gestartet für den Fall 0 und 1! Sollte in dieser Form while den Wert 1 nicht mehr als boolean true auffassen, sondern als integer, und einfach dann starten wenn der vom Instrument ausgespuckte Wert mit 1 übereinstimmt?

Ich hoffe ich habe jetzt Missverständnisse beseitigt und danke nochmals.

Daniel


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 24. Okt 2007 10:34 
Offline
Benutzeravatar

Registriert: 11. Feb 2006 19:10
Beiträge: 3569
Zitat:
Die Funktion (ioctl(acam_fd16, 0x8)&0x0800) liefert einen Wert von 1, wenn die Schleife anfangen soll und 0 wenn sie beendet werden soll.
Diese Funktion liefert 0x0800, falls der ioctl irgendwas zurückliefert, worin dieses Bit gesetzt ist. Also beispielsweise auch bei 0xffffffff, was -1 entspricht (Fehlerfall!).
Zitat:
Daher die Bedingung while(!1):Also falls nicht true, soll das Instrument ausgelesen werden.
Da hast du irgendwo einen Knoten im Gedankengang. Durch das ! wird die Schleife genau solange ausgeführt, wie das Bit aus 0x0800 *nicht* gesetzt ist. Ist das Bit gesetzt oder liefert ioctl einen Fehler zurück, wird die Schleife übergangen.
Zitat:
Gibt es keine Form dies unter ANSI C zu umgehen?
Diese Bedingung ist sowieso kaputt formuliert, weil da keine Fehlerbehandlung drin ist. Für die Ergebnisse von Funktionen, die drei verschiedene Pfade ansteuern, ist while denkbar ungeeignet. Dafür nimmt man for(;;), das ist viel übersichtlicher.
Code:
int lese_schnittstelle&#40;void&#41;
&#123;
  int result;
  int count=0;
  for&#40;;;&#41;
  &#123;
    result=ioctl&#40;acam_fd16, 0x8&#41;;
    if &#40;result<0&#41;
    &#123;
      perror&#40;"Fehler bei ioctl&#40;&#41;"&#41;;
      return -1; /* mit Fehler raus aus der Funktion */
    &#125;
    if !&#40;result&0x800&#41; break; /* ioctl ok, aber Bit nicht &#40;mehr&#41; gesetzt, raus aus der Schleife */

    /* ioctl ok, Daten lesen. */
    ...
  &#125;

  /* Daten gelesen */
  return count
&#125;
Janka

_________________
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 25. Okt 2007 21:27 
Hallo,

danke nochmals.
Also ich habe den Fehlerfall eingebaut wie du beschrieben hast. Das ändert sowieso nichts, da die Funktion nie auf 0xffff gesetzt wird (keine Sorge ich hatte das ja auch ohne der Maske 0x800 überprüft), das Gerät liefert mir auch die richtige Werte für diese Funktion sobald er auch Messwerte bekommt. Technisch gibt es da kein Problem.
Nur will weder die while noch die for Schleife die Messwerte richtig aufsammeln. Noch lustiger, die for Schleife zählt sowohl für den Bit 0 und 1 gesetzt, also für 0 die richtigen Werte und für 1 irgendein Schman.(kein 0xffff).
Die for Schleife habe ich genau so geschrieben wie geschildert.Kann es sein, dass du ein Fehler bei if !(result0x800)gemacht hast? Das Ausführungszeichen muss in die Klammer rein, sonst kompiliert er es nicht.
Also paranoisch kann ich jetzt schon werden.In C++ funktioniert es doch so ohne Problem.

Ich schaue mal weiter,...
Danke nochmals

Daniel


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 25. Okt 2007 22:18 
Offline
Benutzeravatar

Registriert: 11. Feb 2006 19:10
Beiträge: 3569
Zitat:
!(result0x800)gemacht hast?
Tatsächlich. Es muss (!(result&0x800)) heißen.
Zitat:
Das Ausführungszeichen muss in die Klammer rein, sonst kompiliert er es nicht.
Nein. Da müssen dann außen noch Klammern drum, denn (!result&0x800) ist dasselbe wie (!result)&0800, weil ! höherwertig als & ist. (Punkt vor Strich). Und letzteres ist wieder falsch.
Zitat:
Also paranoisch kann ich jetzt schon werden.In C++ funktioniert es doch so ohne Problem.
Mit C++ sollte das gar nichts zu tun haben. Da du vorhin C++ und Linux gegenübergestellt hast (als ob es bei Linux kein C++ gäbe), denke ich, dass es sich um ein Plattformproblem handelt, dass der ioctl eben nicht die richtigen Werte zurückgibt.

Janka

_________________
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.


Nach oben
   
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen  Auf das Thema antworten  [ 6 Beiträge ] 

Alle Zeiten sind UTC+01:00


Wer ist online?

Mitglieder in diesem Forum: Google [Bot] und 1 Gast


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.
Sie dürfen keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
Powered by phpBB® Forum Software © phpBB Limited
Deutsche Übersetzung durch phpBB.de