Datenübergabe
-
Hi,
ich habe 3 Dateien:
data.txt --> dort stehen mehrere Datensätze drin (bitfolgen)
main.exe --> reagiert auf Interrupts und liest dann entsprechend pro Interrupt einen Datensatz ein und schiebt ihn an
driver.exe weiter --> passt Datensatz für Treiberprogramm an (gibt Datensatz erstmal zum testen auf dem Bildschirm aus).
Die Daten aus der .txt Datei zu lesen ist kein Problem. Das ganze funktioniert auch, wenn ich ein Projekt anlege (Borland C++) mit mehreren .c Dateien, die dann zu einer einzigen .exe kompiliert werden. Ich möchte aber das main-programm ein für alle mal fertig haben, so dass ich je nach Treiber nur die driver.exe austauschen muss. Dafür muss ich aber den Datensatz aus main.exe nach driver.exe kriegen. Wie könnte ich das anstellen? Wie gesagt, die Dateien sollen unabhängig voneinander compiliert werden können. Ach ja, das ganze läuft dann unter DOS, kein Konsolenfenster oder so.
Danke schonmal, larsen
-
Wie groß ist, denn so ein Datensatz? Könntest du der driver.exe nicht auch einfach den Dateinamen und die Nummer (Index) des Datensatzes übergeben und das Programm liest den Datensatz selbstständig aus?
-
Hmm,
also so ein Datensatz kann unterschiedlich lang sein, bis zu ca. 250 byte (kennst du dich mit Feldbussystemen aus? So ein Datentelegramm eben).
Also prinzipiell könnte ich das schon so machen, wie von dir angegeben, das Problem dabei ist folgendes: in der Datei stehen ja mehrere Datensätze. driver.exe müsste dann wissen, um den wievielten Datensatz es sich handelt. Also müsste ich dazu auch wieder einen Wert übergeben (Teufelskreis). Ich könnte natürlich auch Kopien der data.txt anlegen, den jeweils ersten Datensatz löschen usw., aber die Interrupts für die nächsten Datensätze kommen im Endeffekt im mikrosekundenbereich, da bin ich mir nicht sicher, ob das nicht zu viel Zeitaufwand wäre.
-
@larsen
Den Index des Datensatzes kannst du an driver.exe ja als Parameter übergeben. argc und argv sagen dir doch was, oder?? Und zum Aufruf von driver.exe benutzt du system():... char kommando[256]; unsigned int index; ... sprintf(kommando, "driver.exe %d", index); system(kommando); ...
-
ja, evtl. wäre das sogar der einfachere Weg, weil ja die Größe des Index relativ konstant bleibt im Gegensatz zur Größe des Datensatzes. Klasse Idee! Ich weiß aber momentan leider nix mit argc und argv anzufangen, und wie ein solcher Index aussehen müsste weiß ich auch noch nicht. Bisher habe ich Die Daten einfach zeilenweise ausgelesen. Na mal sehen. Danke auf jedenfall schonmal für den Denkanstoß.
VG, larsen
-
Mir fällt da noch was ein: wie groß kann so ein Argument werden? Sonst könnte ich ja praktischerweise den Datensatz als Argument übergeben...und so das Dateiöffnen doch main.exe überlassen.
-
Die Grenze hängt vom Betriebssystem ab. Ich schätze bei DOS wird das schon ganz schön knapp mit 250 Byte.
Der Index kann z. B. 2 für den dritten Datensatz sein, wie bei Arrays hald ;). Oder du übergibst driver.exe die genaue Position in der Datei, wo der Satz anfängt (ftell()). Setzt dann den Dateizeiger mittels fseek() auf die entsprechende Position und liest den einen Datensatz aus.
Das mit argc und argv ist recht einfach:
int main(int argc, char *argv[]) { ... }
In argv[0] steht immer der Aufruf deines Programms. Wenn dein Programm (z. B. test.exe) im Ordner prog auf C liegt, dann steht in argv[0] "C:\PROG\TEST.EXE". Die Parameter, die an dein Programm übergeben wurden stehen dann in argv[1] bis argv[argc-1], d. h. in argc steht die Anzahl der Parameter + dem Aufruf. Wenn dein Programm also ohne Parameter aufgerufen wird, dann steht in argc 1 und in argv[0] der Aufruf. Alles klar?
-
danke. Ich probier das einfach aus, wenn ich das nicht hinkriege, melde ich mich nochmal.
VG, larsen
-
@AJ: wie waere es denn, wenn ich den Datensatz, der ja nur aus einer Bitfolge bis zu 255 Zeichen besteht, in main.exe einlese, in eine Dezimalzahl umwandle und dann als Argument uebergebe? Ich habe ja bei DOS fuer die Argumente (inkl. Dateiaufruf) Platz fuer 128 Zeichen...dann kann ich in driver.exe die Zahl wieder zurueckwandeln, weil ich sie sowieso noch modifizieren muss. Ginge das?
-
Hast du 255 Byte oder 255 Bit?
-
ich glaube das geht so nicht, wäre zu langsam und unhandlich. Habe mich jetzt entschieden, das Ganze so zu gestalten:
# include <stdio.h> # include <stdlib.h> # define zeilenlaenge 80 main () { char zeile[zeilenlaenge]; FILE *data; char dateiname[8] = "data"; int endung, index; char ganzer_name[12]; char kommando [15]; for (endung = 1; endung <999; endung++) { sprintf (ganzer_name, "%s.%i",dateiname,endung); data = fopen (ganzer_name,"r"); if (data == 0) { printf ("\nDie Datei \"data.%i\" konnte nicht gefunden werden!\n",endung); break; } else { fclose (data); for (index=0; index<=5; index++) /*können momentan hoechstens 6 Werte pro Datei sein */ { sprintf (kommando, "driver.exe %i", index); system (kommando); delay (1000); } } } }
allerdings würde ich dann die driver.exe einfach "index" mal den Befehl "fgets" aufrufen lassen und dann mit der richtigen Zeile arbeiten. So funktioniert es zwar, aber geht das nicht einfacher? Und noch was: mein Compiler meckert (call to undefined function delay in function main). Warum will der mein delay nicht?
Danke, larsen
-
@ AJ:du hast geschrieben, als ich auch grade geschrieben habe. Deshalb noch eine Antwort hinterher: Im Prinzip habe ich eine Folge aus Nullen und Einsen, also 255 bit. Nachher auf dem Datenbus besteht eine Eins aber aus 10 bit:
1 Startbit + 8 bit für das Zeichen (ASCII) + 1 Paritätsbit + 1 Stopbit
also im Datensatz stehen 255 bit, wenn ich mir das so recht überlege...oder? Besteht nicht eine 1 in einer Textdatei auch aus 1 byte (ASCII)?
jetzt habe ich mich selber verwirrt...
-
@ AJ: Ich habe Mist erzählt. Vergiss einfach meinen Beitrag von eben, es sind tatsächlich 255 bytes (sogar noch ein paar mehr, weil UART-Bytes aus 11 bit bestehen).
sorry, falls es grad etwas konfus war, Lars
-
Aus deinem Code geht aber jetzt hervor, dass du sechsmal driver.exe aufrufst. Jeweils mit dem Index beginnend bei 0 um 1 incrementiert bis einschließlich 5. Macht, finde ich, nicht so viel Sinn. Ich dachte es würde sich nur um einen Datensatz (Index) handeln.
Schneller würde das ganze natürlich schon gehen. Haben deine Datensätze eine feste Größe oder sind sie unterschiedlich groß?
-
die Datensätze sind unterschiedlich groß. Ich muss ja driver.exe so oft aufrufen, weil jeder Datensatz abgearbeitet wird. Ich erkläre das Ganze nochmal im Zusammenhang: in der data.xxx stehen Datensätze, wieviele ist erstmal egal. Das Hauptprogramm kriegt von extern einen Interrupt, daraufhin sollte es den nächstfolgenden Datensatz aus der Textdatei auslesen und an driver.exe übergeben. Diese Datei ist als zusatzmodul gedacht, ich hatte aber keine bessere Idee, als daraus auch eine exe zu machen. Driver.exe verarbeitet dann den Datensatz (wie gesagt, bitfolge, bis zu 260 byte) und schiebt ihn wiederum an das Treiberprogramm der Datenbus-karte weiter. Soweit klar? Also muss ich ja für jeden Datensatz driver.exe einzeln aufrufen und den Datensatz übergeben. Das mit dem Interrupt ist nur noch nicht implementiert, deshalb sieht es so aus, als ob driver.exe 6mal hintereinander aufgerufen wird. Wenn jemand eine bessere Idee hat, ich bin offen für Vorschläge. Das Problem ist ein anderes: da ich die Zeile mit fgets auslese, kann ich ja nicht sagen: fang in der 3. Zeile an. Deshalb muss ich fgets 3mal aufrufen und dann die Zeile auslesen. Geht das einfacher? Und was zum Teufel ist mit dem delay???
VG, larsen
-
Also den Zugriff auf die Datei kannst beschleunigen durch eine sog. Indexdatei. D. h. du speicherst dir die Startpositionen deiner Sätze in einer separaten Datei. Diese liest du nur einmal bei Programmstart ein in ein Array (Zeile 1 = [0], Zeile 2 = [1], ...). Beim Auslesen des Datensatzes setzt du per fseek() den Dateizeiger auf die Position und liest dann den Datensatz aus.
Für deine driver.exe empfehle ich dir, dass du einen eigenen Interrupt baust dafür. Den Interrupt rufst du dann auf, mit deinen Daten bzw. der Information, wo die Daten zu finden sind.
Wenn du wie bisher driver.exe mit sytem() aufrufst, dann kannst du auch gleich die Funktionaltität von driver.exe in einer Funktion ausführen lassen, denn system() kehrt erster wieder zurück, wenn das aufgerufene Programm beendet ist.
-
Interessant, meinst Du eine Funktion in einer separaten Datei? Das müsste nämlich schon so sein, weil es um verschiedene Bussysteme geht, aber die main.exe immer gleich bleiben soll, so dass jemand, der das später bedient, sich nicht mehr damit herumschlagen muss. Ich danke Dir für deine Ideen und Erläuterungen, muss mich aber bis zum nächsten Jahr verabschieden, weil ich nicht vor dem 03.01.05 dazu komme nochwas an dem Programm zu machen (die Uni hat zu
). Dann allerdings würde ich diesen Dialog gerne wieder aufnehmen, wenn ich noch Fragen hab. Dann schöne Feiertage an alle!
VG, larsen