Bugs bei 98% Data und 60% Programm

OP Persönliche Seite #1978257
Lesenswert?

Hallo,

ich habe einen etwas kuriosen Fehler.
Ich habe ein etwas umfangreicheres projekt, welches unter anderem ein 
menü enthält.
Um das Menü dynamischer zu machen, wird für jeden Menüpunkt eine 
Variable mit der Struktur
1
// Menü-Struktur
2
struct menueP{
3

4
  char *name;
5
  
6
  void (*func)(uint8_t);  
7
  uint8_t fdata;
8

9
  struct menueP *prev;
10
  struct menueP *next;
11
  struct menueP *parent;
12
  struct menueP *child;
13

14
};
15

16
struct menueP m1, m2, m3, m4, m5, m11, m12, m13, m21, m22, m23, m31, m32, m33, m34, m35, m36, m41, m42, m51m, m52;
erstellt.

Die Menüpunkte werden zur Laufzeit erstellt (also de Werte zugewiesen).
1
// Neuen Menüpunkt anlegen
2
void new_menueP(char *name, struct menueP* tmp, void (*fu)(uint8_t), uint8_t fud )
3
{
4

5
  // Erstellt einen neuen Menüpunkt
6

7
  tmp -> name = name;
8
  tmp -> func = fu;
9
  tmp -> parent = 0;
10
  tmp -> child = 0;
11
  tmp -> fdata = fud;
12

13
  return;
14

15
}
16

17
// Erstellung der Menüstruktur
18
void init_menue( void )
19
{
20

21
  // Erstellt die Menüstruktur
22

23
  // -----------------------------
24
  new_menueP("01 Zeit/Datum", &m1, NULL, 0);
25
  new_menueP("02 Wecker", &m2, NULL, 0);
26
  new_menueP("03 Farbe", &m3, NULL, 0);
27
  new_menueP("04 Musik", &m4, NULL, 0);
28

29
  m1.next = m3.prev = &m2;
30
  m2.next = m4.prev = &m3;
31
  m3.next = m1.prev = &m4;
32
  m4.next = m2.prev = &m1;
33

34
  // -----------------------------
35

36
  // -----------------------------
37
  new_menueP("11 Zeit", &m11, &m_time, 0);
38
  new_menueP("12 Datum", &m12, &m_date, 0);
39
  new_menueP("13 Geburtstag", &m13, &m_birthday, 0);
40

41
  m11.prev = m12.next = &m13;
42
  m12.prev = m13.next = &m11;
43
  m13.prev = m11.next = &m12;
44

45
  m11.parent = m12.parent = &m1;
46

47
  m1.child = &m11;
48
  // -----------------------------
49
  
50
  // -----------------------------
51
  new_menueP("21 Weckzeit", &m21, &m_time, 1 );
52
  new_menueP("22 Weckmusik", &m22, &m_al_music, 0 );
53
  new_menueP("23 Snoozezeit", &m23, &m_set_snooze, 0 );
54

55
  m21.next = m23.prev = &m22;
56
  m22.next = m21.prev = &m23;
57
  m23.next = m22.prev = &m21;
58

59
  m21.parent = m22.parent = m23.parent = &m2;
60

61
  m2.child = &m21;
62
  // -----------------------------
63

64
  // -----------------------------
65
  new_menueP("31 Farbe setzen", &m31, &m_color, 0);
66
  new_menueP("32 Farbwechsel", &m32, &m_color_switch_mode, 0);
67
  new_menueP("33 Weckfarbe", &m33, &m_color, 1);
68
  new_menueP("34 WeFarbWechs.", &m34, &m_color_switch_mode, 1);
69
  new_menueP("35 Helligkeit", &m35, &m_color_brightness, 0);
70
  new_menueP("36 WeHelligkeit", &m36, &m_color_brightness, 1);
71

72
  m31.next = m33.prev = &m32,
73
  m32.next = m34.prev = &m33;
74
  m33.next = m35.prev = &m34;
75
  m34.next = m36.prev = &m35;
76
  m35.next = m31.prev = &m36;
77
  m36.next = m32.prev = &m31;
78

79
  m31.parent = m32.parent = m33.parent = m34.parent = m35.parent = m36.parent = &m3;
80

81
  m3.child = &m31;
82
  // -----------------------------
83
  
84
  // -----------------------------
85
  new_menueP("41 MP3-Player", &m41, &m_player, 0);
86
  new_menueP("42 Laustaerke", &m42, &m_player_vol, 0);
87

88
  m41.next = m41.prev = &m42;
89
  m42.next = m42.prev = &m41;
90

91
  m41.parent = m42.parent = &m4;
92

93
  m4.child = &m41;
94
  // -----------------------------
95

96
  return;
97

98
}

Meine Menüfunktion wechselt dann entsprechend der Eingabe zum vorherigen 
(prev), nächsten (next) darunterliegenden (child) oder darüberliegenden 
(parent) Menüpunkt, bzw. ruft, falls vorhanden die entsprechende 
Menüfunktion (z.B. Einstellungen vornehmen) auf.

Menüfunktion:
1
// Funktionen für die Menünavigation
2
void menue(struct menueP *tmp)
3
{
4

5
  void (*function)(uint8_t);
6
  uint8_t keybrd;
7

8
  deact_tmr();              // alle Timer aus
9

10
  lcd_bg( 1 );              // Displaybeleuchtung an
11
  lcd_bg_time = 1;            // beleuchtung dauernd an
12

13
  while( tmp ){
14

15
    // -- Innerhalb des Menüs
16

17
    // Funktion zuordnen
18
    function = tmp -> func;
19

20
    // Tastaturpuffer löschen
21
    keybrd = 0x00;
22

23
    
24
    // Anzeigen des Menüpunktes    
25
    lcd_clear();              // Display löschen
26

27
    while( !(keybrd) ){
28

29
      if( _KEYBRD ) _keybrd(&keybrd);    // Tastatur abfragen
30

31
      lcd_string(tmp -> name);        // Menüpunkt-Namen anzeigen
32

33
      // Symbol anzeigen
34
      lcd_setcursor(7,2);
35
      lcd_string(">");
36

37
      // ggf.Funktion aufrufen
38
      if( (keybrd & BTN_ENTER) && *function ){
39
        
40
        // Display löschen
41
        lcd_clear();
42

43
        // Tastaturpuffer löschen
44
        keybrd = 0x00;
45

46
        // Funktion aufrufen
47
        (*function)(tmp -> fdata);
48

49
        // Tastaturpuffer löschen
50
        keybrd = 0x00;  
51
        
52
        // Display löschen
53
        lcd_clear();    
54

55
      }
56

57
      // Warten auf Benutzereingabe
58
      if( (keybrd & BTN_MENUE) ) tmp = tmp -> parent;          // nach oben
59
      if( (keybrd & BTN_ENTER) && !function ) tmp = tmp -> child;    // nach unten
60
      if( (keybrd & BTN_UP) ) tmp = tmp -> prev;            // zurück
61
      if( (keybrd & BTN_DOWN) ) tmp = tmp -> next;          // vorwärts
62

63
      _delay_ms(100);
64

65
    }
66

67
  }
68

69
  lcd_clear();    // Display löschen
70
  act_int();       // alle Timer wieder an
71

72
  flash_time = 0;    // Alarmflag aus  
73
  lcd_bg_time = 0;  // LCD Hintergrundbeleuchtung aus
74

75
  _delay_ms(100);
76

77
}

Das Funktioniert auch einwandfrei.

Füge ich jetzt aber einen weiteren mMenüunkt '05' mit zwei Unterpunkten 
hinzu, über die Einstellungen im EEPROM gespeichert bzw. aus dem EEPROM 
geladen werden sollen, erscheinen beim Wechsel von Punkt 02 zu 03 oder 
von 04 zu 03 nur kryptische Zeichen auf dem Display und eine Steuerung 
ist nicht möglich.
Teilweise wird beim Drücken der Menütasten dann auch meine Startfunktion 
(die alles initialisiert) aufgerufen, was sonst nur in der main() vor 
meiner while(1){...}-Schleife (aus der wird das Menü aufgerufen) 
geschieht.

Der Datnespeicher ist dann auch bei 98% und der Programmspeicher bei 60%
Der Menüpunkt '05' funktioniert einwandfrei.

Ich vermute, dass die Variable für Menüpunkt 03 irgendwo am Ende des 
RAMs liegt und die Speicherzelle nicht richtig beschreibbar ist (ev. ist 
dort der Bootloader?).



Kann mir jemand helfen, dieses Problem zu lösen?
Moderator (Firma: Titel) Persönliche Seite #1978276
Lesenswert?

Hannes E. schrieb:
> Teilweise wird beim Drücken der Menütasten dann auch meine Startfunktion
> (die alles initialisiert) aufgerufen,
Passiert dann beim Drücken einer Taste immer das selbe?
Oder jedesmal was anderes?

> Ich vermute, dass die Variable für Menüpunkt 03 irgendwo am Ende des
> RAMs liegt und die Speicherzelle nicht richtig beschreibbar ist
Der Stack braucht auch noch Platz im Datenspeicher...
#1978310
Lesenswert?

Hannes E. schrieb:
> Würde es dazu nicht genügen Variabeln mit den Strings als Wert zu
> initialisieren?

Nein.
Im Moment machst du dir dein SRAM mit Texten dicht, die eigentlich kein 
Mensch im SRAM braucht.

> Durch die Seite (hinterm Link) steige ich noch nicht ganz durch.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29

> Das bläst meinen RAM doch nur noch mehr auf oder?

Das genaue Gegenteil ist der Fall.
Das entlastet dein RAM

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren