Forum: Mikrocontroller und Digitale Elektronik Merkwuerdiges Verhalten von SDCC mit STM8


von Ralph S. (jjflash)


Lesenswert?

Ich bin schier am Verzweifeln:

Ich bastle immer noch (oder immer wieder) an Softwaremodulen für STM8 
unter SDCC (weil Linux).

So... war ich am Anfang noch freudig überrascht dass das relativ einfach 
funktionierte, wächst nun der Frust und ich glaube SDCC ist dafür 
verantwortlich.

Ich kann schwierig an Codebeispielen erklären was nicht so recht 
funktioniert, aber mich beschleicht langsam das Gefühl, dass die RAM und 
Stack - Verwaltung des SDCC's in Verbindung mit STM8 buggy ist.

Schreibe ich eine Codesequenz, die funktioniert und lagere ich diese in 
eine Funktion aus, funktioniert sie plötzlich nicht mehr (obwohl ich sie 
mittels Copy und Paste aus meiner eigenen Main dorthin verfrachtet hab.) 
Ich weiß sehr wohl, dass ein Funktionsaufruf den Stack belastet.

Erweitere ich ein Programm, bleibt manchmal dieses weit vor Erreichen 
des neuen Programmteils hängen. Dann funktioniert manchmal ein
1
volatile char dummy;
2
3
dummy= 5;
4
dummy= dummy;

oder ähnlicher nutzloser Programmcode, der nichts sinnvolles ausführt, 
vor einem neuen Programmteil und der Code funktioniert wieder.

Ich habe mittlerweile Codeanalyse der erzeugten ASM und MAP-Dateien 
betrieben und durchschaue einiges, aber nicht alles.

Am Schlimmsten ist wohl, dass ich nirgendwo, das Ende des Stacks 
initalisieren kann und ich (ich bin wieder am Lesen des Datenblatts) 
schlicht davon ausgehe, dass der Stackpointer auf das Ende des RAMS nach 
dem Einschalten liegt.

Im Datenblatt steht:

In the default stack model this pointer is initialized to the
RAM end address.

Sind die Resetwerte der STM8 - Serie tatsächlich so, dass der 
Stackpointer auf das Ende des Rams zeigt und mit Verwendung dem 
RAM-Anfang (in dem Variable abgelegt sind) entgegen wächst?

Kann ich mich darauf verlassen ... oder liegt mein Fehler irgendwo 
anderst in bspw. der Initialisierung?
1
/* ------------------------------------------------------
2
                     sysclock_init
3
      stellt den Taktgeber fuer den Controller ein.
4
      Bei Verwendung des internen Oszillators werden
5
      16MHz eingestellt
6
7
      (Xtal enable) xtalen = 1  => externer Quarz
8
                           = 0  => interner RC-Oszillator
9
10
      Anmerkung:
11
         soll der MCU mit externem Quarz laufen, ist
12
         zuerst ein Aufruf
13
14
            sysclock_init(0);
15
16
         gefolgt von einem Aufruf
17
18
            sysclock_init(1);
19
20
         zu erfolgen !
21
   ------------------------------------------------------ */
22
void sysclock_init(char xtalen)
23
{
24
  if (xtalen)
25
  {
26
    CLK_ICKR = 0;                                  //  Reset Register interner clock
27
    CLK_ECKR = HSEEN;
28
29
    while ((CLK_ECKR & HSERDY) == 0);              //  warten bis Quarz eingeschwungen ist;
30
31
    CLK_SWR = 0xb4;                                //  int. Generator als Taktquelle
32
    CLK_SWCR = SWEN;                               //  Enable switching.
33
34
    CLK_CKDIVR = 0;                                //  Taktteiler auf volle Geschwindigkeit
35
    CLK_PCKENR1 = 0xff;                            //  alle Peripherietakte an
36
    CLK_PCKENR2 = 0xff;                            //  dto.
37
  }
38
  else
39
  {
40
    CLK_ICKR = 0;                                  //  Reset Register interner clock
41
    CLK_ECKR = 0;                                  //  Reset Register externer clock (ext. clock disable)
42
43
    CLK_ICKR =  HSIEN;                             //  Interner clock enable
44
    while ((CLK_ICKR & (HSIRDY)) == 0);            //  warten bis int. Takt eingeschwungen ist
45
46
47
    CLK_CKDIVR = 0;                                //  Taktteiler auf volle Geschwindigkeit
48
    CLK_PCKENR1 = 0xff;                            //  alle Peripherietakte an
49
    CLK_PCKENR2 = 0xff;                            //  dto.
50
51
    CLK_CCOR = 0;                                  //  CCO aus
52
    CLK_HSITRIMR = 0;                              //  keine Taktjustierung
53
    CLK_SWIMCCR = 0;                               //  SWIM = clock / 2.
54
    CLK_SWR = 0xe1;                                //  int. Generator als Taktquelle
55
    CLK_SWCR = 0;                                  //  Reset clock switch control register.
56
    CLK_SWCR = SWEN;                               //  Enable switching.
57
    while ((CLK_SWCR &  SWBSY) != 0);              //  warten bis Peripherietakt stabil
58
  }
59
}

Das war bisher meine Initialisierung (es werden keine anderen 
Initialisierungen vorgenommen) und hat bei den bisherigen kurzen 
Programmen (mit wenig RAM - Verwendung und ca. 5 Stackebenen) auch gut 
funktioniert, aber schön langsam ist der Wurm drin ...

Kann man an den RAM Einstellungen in Verbindung mit STM8 etwas 
einstellen?

In meiner Not bin ich sogar hergegangen, hab (im jetzigen Programm) das 
Hardware I2C absichtlich nicht verwendet, eine softe I2C - 
Implementierung geschrieben und das ganze Programm so geschrieben, dass 
es bis auf das Bitbanging der Ports und das Initialisieren eines Timers 
identisch für einen AT89S52 ist ... und siehe da, auf diesem MCU macht 
der SDCC keine Mucken, nur für den STM8.

Der Timerinterrupt verwendet keine 16-Bit Variable, nur uint8_t Typen 
(weil ich mir erst überlegte, ob ein Interrupt mir vllt. zwischen einer 
soften 16-Bit Rechenoperation dazwischen spuckt und nach dem Interrupt 
die Register nicht mehr ihre Inhalte aufweisen).

Hey, ihr könnt mir gerne die Rübe abhauen ... aber bitte von 
Beleidigungen abstand nehmen.

Die Dinge hab ich für MCS-51, für AVR und (nach langer Kleinarbeit) auch 
für STM32 und LPC hinbekommen ...

Weiß irgendjemand etwas über Bugs vom SDCC ganz im Speziellen mit der 
Speicherverwaltung ?

von Philipp Klaus K. (pkk)


Lesenswert?

Was für ein STM8 ist es denn? Welche Version von SDCC?
Zu Problemen mit dem Stackzeiger fällt mir nur das ein:
http://wiki.chibios.org/dokuwiki/doku.php?id=chibios:articles:stm8_stack
allerdings war ich bisher noch nicht von dem Problem betroffen.

Zur Zeit gibt es in SDCC keine offenen STM8-spezifischen Bugs.

Philipp

von Philipp Klaus K. (pkk)


Lesenswert?


von Ralph S. (jjflash)


Lesenswert?

... ich habs jetzt analysiert .... uuuuund der Fehler liegt 
ausnahmsweise nicht bei mir (denn bei mir such ich immer zuerst) . Aus 
irgendeinem Grund räumt der SDCC in bestimmten Konstellationen nach 
einem CALL manchmal den Stack nicht auf, was heißt ein abschließendes 
POP fehlt im Assemblercode... Nachdem ich Programm weitergeschrieben 
hab, kann ich den Fehler noch nicht einmal mehr reproduzieren... leider. 
Sonst hätte ich das Programm zu Analyse eingereicht. Aber danke für 
deine Rückmeldung.

von Bernd K. (prof7bit)


Lesenswert?

Ralph S. schrieb:
> Nachdem ich Programm weitergeschrieben
> hab, kann ich den Fehler noch nicht einmal mehr reproduzieren...

Ein Wort: Versionsverwaltung.

von Ralph S. (jjflash)


Lesenswert?

Bersionsverwaltung.... bin ich (leider) sowas von schlampig.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.