Forum: Projekte & Code StackViewer (RAM Rechner) für WinAVR


von Benedikt K. (benedikt)


Lesenswert?

Diese Software errechnet den gesamten RAM Verbrauch einer Software 
(inkl. Stack!) und erstellt eine Datei mit der Baumstruktur welche 
Funktion welche aufruft.
Dazu wird die vom Compiler erstellte ELF Datei mittels der ELFIO Lib 
eingelesen, der Maschinencode, die Symboltabelle (welche Funktion an 
welcher Adresse steht) und die globale Variablengröße extrahiert.
Nun spielt die Software das Programm einmal komplett durch, betrachtet 
aber nur calls und andere Stack manipulierende Befehle. So wird der 
maximale Stackverbrauch ermittelt.

Das funktioniert für "normale" Programme ganz gut, es gibt allerdings 
ein paar Situationen in denen die Software scheitert (diese erzeugen 
eine Warning):
- icalls (Program Pointer): Da diese erst zur Laufzeit ermittelt werden, 
können diese nicht ausgeführt werden.
- rekursive Funktionen: Da diese eine Endlosschleife bewirken, werden 
auch diese nicht ausgeführt.
- nested Interrupts. Hier gilt ähnliches wie bei rekursiven Funktionen.

Solange keine der obigen Situationen auftreten, sollte die Berechnung 
exakt sein (falls ich nicht irgendeinen Fehler eingebaut habe.)

Diese Software ist nicht wirklich ausgereift! Eigentlich war es eine 
quick&dirty Lösung um einen Fehler zu finden (den ich auch gefunden 
habe: Es lag tatsächlich am Stack!).
Da ich die Software aber als sehr nützlich erachte, stelle ich das 
Programm inkl Source hier rein. Der Code ist aber alles andere als 
ordentlich programmiert.

In der Software habe ich aus Gründen der Einfachheit etliche Annahmen 
getroffen (die einen Error erzeugen wenn sie nicht zutreffen, bzw. das 
Programm abstürzt) wie z.B.
- eine Abschätzung der Flashgröße (notwendig für die rjmp/rcall Sprünge 
über die Flashgrenze hinweg)
- der Code steht in der Section die .text heißt
- der Einstiegspunkt ist die Funktion die in der Symboltabelle main 
heißt
- bestimmte Befehlskombinationen mit dem der Compiler Stack belegt (in 
rx,SPL/SPH, sbiw rx, n)
- und noch ein paar weitere.

Ich habe das Programm ein wenig getestet, mit allen getesteten 
Programmen funktionierte die Software bei mir (was natürlich nicht 
heißt, dass es mit allen Compilerversionen auch wirklich geht). Falls 
jemand ein Programm hat das nicht laufen sollte, bitte das gesamte 
Projekt (Source, lst, lss, elf Dateien) als zip hier posten. Falls ich 
Zeit habe, werde ich versuchen das Problem zu lösen.

von Benedikt K. (benedikt)


Angehängte Dateien:

Lesenswert?

Hier das Programm

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Oha, das sieht interessant aus! Danke Benedikt.

von Benedikt K. (benedikt)


Angehängte Dateien:

Lesenswert?

Hier eine neue Version mit einem kleinen Update das eine 
Zweckentfremdung von rcall zur Belegung von Stack erkennt.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Hi, in meinen Programmen verwende ich zum Testen den freien Speichers 
das:

http://www.roboternetz.de/wissen/index.php/Speicherverbrauch_bestimmen_mit_avr-gcc#Dynamischer_RAM-Verbrauch

Das belegt nur 46 Bytes Flash!

Allerdings ist es natürlich keine statische Analyse, sondern gibt nur 
eines Hinweis wieviel Speicher noch frei ist. Und man braucht einen Weg, 
an den Wert zu kommen (Dislpay, UART, ...)

von Stefan E. (sternst)


Lesenswert?

Ich habe das Programm mal ausprobiert. Leider scheint es nicht zu 
erkennen, wenn für größere lokale Variablen der Stackpointer direkt 
manipuliert wird.

1
uint32_t func ( uint8_t c ) {
2
3
  uint8_t str[100];
4
...
1
uint32_t func ( uint8_t c ) {
2
  4e:  df 93         push  r29
3
  50:  cf 93         push  r28
4
  52:  cd b7         in  r28, 0x3d  ; 61
5
  54:  de b7         in  r29, 0x3e  ; 62
6
  56:  c4 56         subi  r28, 0x64  ; 100
7
  58:  d0 40         sbci  r29, 0x00  ; 0
8
  5a:  0f b6         in  r0, 0x3f  ; 63
9
  5c:  f8 94         cli
10
  5e:  de bf         out  0x3e, r29  ; 62
11
  60:  0f be         out  0x3f, r0  ; 63
12
  62:  cd bf         out  0x3d, r28  ; 61
1
function: main                size: 4
2
  function: func              size: 45
3
  end function                local stack:     4, total stack:     6
4
end function                  local stack:     2, total stack:     2

von Benedikt K. (benedikt)


Angehängte Dateien:

Lesenswert?

Probiers mal mit dieser Version aus. Bei dieser sollte die Berechnung 
passen.

von Stefan E. (sternst)


Lesenswert?

Ja, sieht besser aus, danke.

von Steffen L. (slo)


Lesenswert?

Hallo,

erst mal vielen Dank für dieses hilfreiche Programm!

Ich habe den Eindruck, dass der EEPROM-Verbrauch und der SRAM-Verbrauch 
nicht getrennt werden.

Ausgabe von StackViewer:
1
global RAM usage (bytes):          980

Ausgabe von avr-size:
1
Data:        852 bytes (83.2% Full)
2
(.data + .bss + .noinit)
3
4
EEPROM:      128 bytes (25.0% Full)
5
(.eeprom)

852 + 128 = 980

Grüße.

von Matthias N. (nippey)


Lesenswert?

Vielen Dank, das hat mir sehr geholfen! Habe die Ausgabe direkt nach 
avr-size in meine Toolchain eingebaut ;)

Ich würde vorschlagen es hier
http://www.mikrocontroller.net/articles/AVR_Softwarepool
o.ä. zu verlinken!

von Olaf D. (Firma: O.D.I.S.) (dreyero)


Lesenswert?

Hallo Benedikt,

ich habe mir die Stackview Sourcen vom github besorgt.
Sind die neuer als die in dem hier veröffentlichen ZIP File?
Auf meinem amd64 (Gentoo) stürzte des elfdump Programm immer ab.
Den Fix dazu würde ich gerne veröffentlichen bzw. dir / der Community 
zurückgeben.

Muss ich dazu extra einen GIT Server aufsetzen, oder kann ich dir 
einfach ein Patchfile zur Verfügung stellen?

Gruß

Olaf

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.