www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430 C-Funktionen vom RAM ausführen?


Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weiß jemand, wie man auf dem MSP430 eine C-Funktion in den RAM kopiert,
und von da ausführt?
Ich möchte den gesamten FLASH neu beschreiben können, dazu muss die
Flash-Routine in den RAM.
Speicher hab ich genug, der F1611 hat intern 10k RAM und extern hängen
nochma 1MByte dran, da würde ich das TI txt file ablegen.
Nur müsste ich vor dem Flaschen meine Funktion in den RAM laden.
Wie macht man das?

Ich benutze den MSP-GCC.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
memcpy?

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achnee. Und woher weiß ich, wie groß meine auszuführende Funktion ist? 
Kann man sich die Größe einer Funktion im C irgendwie holen? Mit 
sizeof() bekomm ich nur die größe des Pointers wie es scheint, also 1.

Am liebsten würd ich dem Linker gleich sagen, er soll meine Funktion in 
den RAM packen, aber da hab ich auch keine Infos gefunden, wie das geht.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Grundsätzlich verhindert die MSP430 dein Vorhaben nicht

Beitrag "MSP430 + Execution from RAM"

Ich kenne es nur vom ARM her. Dort kann man seinen Code komplett oder in 
Teilen z.B. in die .data Section legen lassen oder eine Section mit 
eigenem Namen.

http://www.embeddedrelated.com/groups/lpc2000/show/5031.php

Hat MSPGCC das _attribute_ section? Ich denke ja, hier ist zumindest 
beschrieben, wie man Code und Daten gezielt im Flash ablegen kann.

http://mspgcc.sourceforge.net/faq/x71.html

IMHO könnte das auch im RAM funktionieren und wenn man beachtet, ab wann 
das RAM initialisiert ist bzw. seinen Startup-Code so umschreibt, dass 
die ggf. verwendete eigene Section auch vom ROM ins RAM kopiert wird. 
Oder man steckt unschön die Funktion mit in die .data Section und lässt 
kopieren.

Die Grösse der eigenen Section bekommt man ja über das 
Linkercontrolscript heraus bzw. man kann sich entsprechende *start/*end 
Variablen definieren. Das und die Kopieraktion kann man bei der .data 
Section abkucken.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke. Ich schau mal, ob ich das in eine eigene FLASH-Page bekomme, die 
kann ich dann ja ins RAM zur Laufzeit kopieren.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es muss keine eigene Flash-Page und "manuelles" Kopieren sein. Klar das 
geht auch. Du musst dann aber dem Compiler/Linker bekanntmachen, dass du 
eine private Flash-Page und einen privaten RAM Abschnitt hast, in den 
die Toolchain nix legen darf. D.h. also auch das Linkercontrolskript 
anpacken. Für den Funktionsaufruf zur RAM-Funktion bräuchtest du dann 
Funktionspointer bzw. Inline-Assembler. Du musst auch darauf achten, 
dass der Code an der RAM Zieladresse lauffähig ist. Also die Toolchain 
für den Code ggf. entsprechende absolute Adressen oder relative Calls 
produziert.

Eleganter finde ich die Methode über die section. Hier kann es ein 
beliebiger Abschnitt (section) im Flash sein und die Toolchain kümmert 
sich um den passenden Code. Die treffende Benennung des Abschnitts ist 
für den Linker, fürs eigene Verständnis und für elegantes Programmieren 
;-) nützlich. Es ist aber nicht notwendig, denn man kann 
(wahrscheinlich, ausprobiert habe ich es nicht) den Code auch in der 
.data section unterbringen und die wird eh automatisch beim Startup vom 
Flash ins RAM kopiert.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der MSP führ den Code aus dem FLASH aus, da wird nix in den RAM kopiert. 
Wie auch, bei den paar Bytes. Das ist kein ARM :)

Mit der section ist ne gute Idee, da muss ich dann nichtmal ins RAM 
kopieren, denn der MSP kann sich sogar selber flashen, wenn die 
flash-routine selbst aus dem Flash kommt. Nur steht dann halt die CPU.

Ist denn sichergestellt, dass im betreffenden FLASH-Segment dann kein 
anderer Code als der markierte steht? So ganz eindeutig ist die FAQ bei 
mspgcc da nicht....

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Der MSP führ den Code aus dem FLASH aus, da wird nix in den RAM kopiert.
> Wie auch, bei den paar Bytes. Das ist kein ARM :)

Sorry. Ich dachte du willst dies:

> Weiß jemand, wie man auf dem MSP430 eine C-Funktion in den RAM kopiert,
> und von da ausführt?

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das würde ich am liebsten machen. Dazu muss ich allerdings meine 
FLASH-Funktion in einem Bereich ablegen, den ich genau kenne, also Start 
und Größe.

Der MSP macht von alleine nix mit Startup und ins RAM kopieren.

Es gibt 2 Möglichkeiten:

1. Die Update-Funktion liegt in einem geschützten Bereich im FLASH und 
wird von da ausgefäührt. Beim Flaschen wird dieser Bereich nicht 
gelöscht. Klassische Bootloader-Variante.

2. Die Updatefunktion liegt irgendwo in Flash. Auf Befehl wird diese 
Funktion aus dem Flash in den RAM kopiert und dann von dort ausgeführt.

Variante 2 hat den Vorteil, dass man den kompletten Flash neu 
beschreiben kann, also man kann auch den Bootloader ändern.

Leider hab ich erst ma zwischendurch wieder an einem anderen Projekt zu 
tun, deswegen kann ich da noch nicht weiter machen.

Hätte ja sein können, das hat schon mal einer gemacht.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Der MSP macht von alleine nix mit Startup und ins RAM kopieren.

Habe ich das behauptet, dass er das alleine macht?

Der Startupcode deines Programms macht das. Der Teil die MSPGCC 
Toolchain vor deiner ersten Programmanweisung ("main()") hinzugefügt 
hat.
http://mspgcc.sourceforge.net/manual/x1127.html

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Abschliessend (meinerseits) noch ein interessanter Link zum Thema:

Konstruktion und Regelung eines autonomen Zweirad-Roboters

Carsten Fuhrmann und Andreas Tenge implementieren in ihrer Diplomarbeit 
die Reglerroutinen für den Roboter im RAM. Die Vorgehensweise ist sehr 
ausführlich und anschaulich beschrieben.

http://www.ti.uni-bielefeld.de/downloads/publicati...

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beim C166 (Infineon, ähnliche Architektur) machen wir das 
folgendermaßen:
Wir haben uns eine Funktion memswitch() geschrieben, die folgendermaßen 
funktioniert:

1. Flashinhalt in RAM kopieren (komplett).
2. Chip Select von RAM und Flash vertauschen (memory mapping)

fertig. danach läuft das Programm wie gewohnt weiter, nur eben aus dem 
RAM. Man sollte natürlich die Interrupts während der Routine abschalten 
und die Register sichern. Unser memory mapping sieht wie folgt aus:
Man muß beim linken darauf achten, das man die Variablen in einen Teil 
des RAMs linkt, welcher später nicht überschrieben wird (z.B. oberer 
Teil des RAMs)

Autor: arc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kein schöner Stil, sollte aber funktionieren.
Wichtig ist, dass die eigentlichen Flashroutinen nur 
positionsunabhängigen Code enthalten (was zumindest beim IAR eingestellt 
werden kann)
// festgelegte Adresse im RAM für die kopierte Funktion
uint16_t* destFunc = 0x1234;

// Kopierroutine
void flashToRAM(uint16_t* dest, const uint16_t* src, uint16_t len);
void flashToRAM(uint16_t* dest, const uint16_t* src, uint16_t len) {
  len >>= 1;

  while (len) {
    *dest++ = *src++;
    len--;
  }
}

// Dummyroutinen zum Flashen
void writeFlash() {
  P4OUT = 123;
}

void writeFlashEnd() {
}

// Kopieren
flashToRAM(destFunc, (uint16_t *)&writeFlash, (uint16_t)&writeFlashEnd - (uint16_t)&writeFlash);
// Aufrufen
void (*RAM)() = (void (*)())destFunc;
RAM();

Autor: Veit Wehner (veitwehner)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
im Grund ist die Grösse gleich der Differenz der Funktionspointer zweier 
aufeinanderfolgender Funktionen im C Code. Hast Deine CPU eine 
Befehlslaenge von einem Byte, kannste zwei Funktionspointer vom Typ char 
voneinander subrahieren und bekommst die Funktionsgroesse in Byte.
Bei einem optimierenden Compiler koennts Probleme geben, wenn er zum Bsp 
kleine Funktionen "inlined". Das duerfte er aber eigentlich nicht tun, 
wenn der C Code einen Funktionspointer darauf besitzt.
Wenn man mit gcc -S uebersetzt, kann man am Zwischencode sehen, wie der 
Compiler das arrangiert

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.