Programmierer-Rätsel

SIxO Sourcecode, Programmieren und Entwicklungswerkzeuge allgemein
Antworten
markus
Site Admin
Beiträge: 160
Registriert: 19 Feb 2004 - 15:49
Wohnort: Ammersee
Kontaktdaten:

Programmierer-Rätsel

Beitrag von markus »

Weiß gar nicht wo ich anfangen soll... ist alles so seltsam, was ich eben erleben musste. Ich probiers mal so:

in resource.h:

Code: Alles auswählen

#define MAX_STATE_TEXT_LEN        18  /* maximum characters printable in status line, excl. null terminator */
#define RESTXT_STATE_WATERTEMP    "Kühlwasser zu heiß"
#define RESTXT_STATE_OILTEMP      "Öl zu heiß"
#define RESTXT_STATE_ENGINE_COLD  "Motor noch kalt"
#define RESTXT_STATE_VOLTAGE      "Spannung niedrig"
#define RESTXT_STATE_ALLRIGHT     " Alles ok"
ziemlich unspannend.

Und dann in mondev.c:

Code: Alles auswählen

static char far           *szStateDescs[LAST_VEHICLE_STATE_PARM];  /* parameter names */
static char far           *szStateAllRight;
static char                szState[MAX_STATE_TEXT_LEN+1];
...

void MonDevInit(void)
{
...
    szStateAllRight                        = RESTXT_STATE_ALLRIGHT;
    szStateDescs[VEHICLE_STATE_WATTEMP]    = RESTXT_STATE_WATERTEMP;
    szStateDescs[VEHICLE_STATE_OILTEMP]    = RESTXT_STATE_OILTEMP;
    szStateDescs[VEHICLE_STATE_ENGINECOLD] = RESTXT_STATE_ENGINE_COLD;
...
jetzt wird's spannend: ich will den Status-Puffer mit szStateAllRight initialisieren, also

Code: Alles auswählen

strcpy(szState, szStateAllRight);
im Display erscheint aber "Motor noch kalt". Komisch. Mal mit DebugOut anschaun, was in szState steht:

Code: Alles auswählen

DebugOut("state init to: ");
DebugOut(szState);
KAWUMM, der arme SIxO fliegt auf die Nase, Absturz. "init state:" seh ich noch im Terminal, dann ist Ende. Häääh?

Nach langem Rätseln war ich verzweifelt und habe folgendes geschrieben:

Code: Alles auswählen

    for (i = 0; szStateAllRight[i] != 0x00; i++) {
        szState[i] = szStateAllRight[i];
    }
    szState[i] = 0x00;
    DebugOut("state init to:");
    DebugOut(szState);
Kein KAWUMM! Im Terminalfenster erscheint "state init to:Motor noch kalt." Ist der strcpy doof???

Jetzt will ichs wissen:

Code: Alles auswählen

DebugOut(RESTXT_STATE_ALLRIGHT)
Na, was erscheint im Terminal? "Alles ok" erscheint...

Vielleicht isses ja schon zu spät und ich seh den Wald vor lauter Bäumen nicht, aber warum fliegt er nach dem strcpy auf die Nase? Und warum ist szSate immer "Motor noch kalt", anstatt "Alles ok"??

Rätselt mal schön, ich geh jetzt schlafen. :evil:

Ralf
Beiträge: 569
Registriert: 20 Feb 2004 - 11:27
Wohnort: Hannover

Re: Programmierer-Rätsel

Beitrag von Ralf »

Hi Markus, was mir gerade so beim überfliegen auffällt:

Code: Alles auswählen

DebugOut("state init to:");
DebugOut(szState);
Demnach gehen deine DebugOuts schon, nur die über das Makro ODSx()nicht, richtig?

Code: Alles auswählen

#define MAX_STATE_TEXT_LEN        18  /* maximum characters printable in status line, excl. null terminator */
#define RESTXT_STATE_WATERTEMP    "Kühlwasser zu heiß"
#define RESTXT_STATE_OILTEMP      "Öl zu heiß"
#define RESTXT_STATE_ENGINE_COLD  "Motor noch kalt"
#define RESTXT_STATE_VOLTAGE      "Spannung niedrig"
#define RESTXT_STATE_ALLRIGHT     " Alles ok"
Dazu zwei Dinge:
1. "Kühlwasser zu heiß" hat exakt MAX_STATE_TEXT_LEN Zeichen, ist hier das Problem?
2. Auf Sonderzeichen wie ü/ö/ä/ß reagieren Compiler sehr empfindlich bis undefiniert! Du solltest sie auf jeden Fall durch die entsprechende '\xhh' Sequenz ersetzen (hh ist der Hex-Code des Zeichens).

Code: Alles auswählen

strcpy(szState, szStateAllRight);
Evtl. hättest du das mit

Code: Alles auswählen

strcpy(szState, RESTXT_STATE_ALLRIGHT)
kürzer haben können?

Code: Alles auswählen

DebugOut("state init to: ");
DebugOut(szState);
Wir arbeiten im Sourcecode immer nur mit dem Type STRING (char far *). Probier doch mal den Typecast darauf mit

Code: Alles auswählen

DebugOut( (char far *)szState);
Wenn ich mich recht erinnere, frisst die 'strcpy()' und 'printf()' Funktion der NC30-Standard-Lib nur far-Ptr. auf Strings, schau doch mal bitte in dem NC30 UserManual nach!
Ralf

markus
Site Admin
Beiträge: 160
Registriert: 19 Feb 2004 - 15:49
Wohnort: Ammersee
Kontaktdaten:

Beitrag von markus »

Hi Ralf,

vielen Dank für die Antwort, weiss ich sehr zu schätzen :)

>Demnach gehen deine DebugOuts schon, nur die über das Makro ODSx()nicht, richtig?

Genau. Für mich sieht es wie gesagt so aus, als würde er die Debug-Einstellungen mit Werten aus dem EEPROM so überschreiben, dass nix mehr rausgeht. Wenn ich DebugOut direkt aufrufe, dann geht's.

>1. "Kühlwasser zu heiß" hat exakt MAX_STATE_TEXT_LEN Zeichen,
>ist hier das Problem?

Glaub ich nicht. szState ist definiert als szState[MAX_STATE_TEXT_LEN+1], das sollte hinhauen.

Das mit den Sonderzeichen werd ich ausprobieren. Da hab ich aber auch nicht viel Hoffnung; der Text "Öl-Temp" (statischer Text) erscheint im MonitorDevice richtig.

>Evtl. hättest du das mit
>strcpy(szState, RESTXT_STATE_ALLRIGHT)
>kürzer haben können?

Schon, aber ich bin ein sparsamer Mensch :wink: das käme im Code drei mal (oder so), wenn ich nur den Pointer referenziere, steht der String nur einmal im Object-File. Vielleicht übertrieben sparsam, aber sollte doch gehen???

>Probier doch mal den Typecast darauf mit
>DebugOut( (char far *)szState);

Das riecht nach mehr!! Interessante Frage, was der Compiler macht, wenn man Arrays ohne Suffix referenziert: far oder near Pointer?? Super-Tip, probier ich morgen gleich aus! Ich hatte allerdings schon mal ein Warning vom Compiler, dass er bei irgendeinem Aufruf aus einem far einen near Pointer machen musste und die Bank-Info verloren geht. Vielleicht warnt er hier aber nicht...

strcpy ist in string.h definiert als

Code: Alles auswählen

char _far * strcpy(char _far *s1, const char _far *s2);
Danke nochmal!

Gruß
Markus

markus
Site Admin
Beiträge: 160
Registriert: 19 Feb 2004 - 15:49
Wohnort: Ammersee
Kontaktdaten:

Beitrag von markus »

Ok, für alle, die beim Rätsel mitgefiebert :D haben, hier kommt die Lösung:

Das Pointer Array für die Statustexte war zu klein:

Code: Alles auswählen

static char far           *szStateDescs[LAST_VEHICLE_STATE_PARM];  /* parameter names */ 
muss aber heissen

Code: Alles auswählen

static char far           *szStateDescs[LAST_VEHICLE_STATE_PARM+1];  /* parameter names */ 
Diese Anweisung hat dann szStateAllRight überschrieben (weil szStateAllRight direkt hinter dem Array im Speicher stand):

Code: Alles auswählen

szStateDescs[VEHICLE_STATE_ENGINECOLD] = RESTXT_STATE_ENGINE_COLD
Computer sind doch geil :mrgreen:

Antworten