Hallo, neuere Mikrocontroller haben inzwischen ja meist so viel SRAM, dass man auf die Idee kommen kann, beim Debuggen das Programm nur ins RAM zu laden und dort laufen zu lassen. Für den STM32 habe ich dazu ein Trampolin ins Flash geschrieben, dass nach einem Reset den Stack aus 0x20000000 lädt und dann nach 0x20000004 springt. Hat man im Linker Skript etwas wie .text:{ *(.text .text.* .gnu.linkonce.t.*) *(.rodata .rodata* .gnu.linkonce.r.*) } > SRAM0 .data : { *(.data .data.* .gnu.linkonce.d.*) . = ALIGN(4); *(.ramfunc); . = ALIGN(4); } > SRAM0 geht das aber nach dem Hochladen nur einmal, das die initialisierten Daten im ersten Lauf verändert werden. Damit das Ganze auch auch nach einem Programmlauf neu Starten kann, bräuchte man einen Bereich im SRAM, aus dem die initialisierten Daten jedesmal neu geladen werden, wie in Linkerskripten für Flash. Allerdings bringt .text:{ *(.text .text.* .gnu.linkonce.t.*) *(.rodata .rodata* .gnu.linkonce.r.*) .etext = .; } > SRAM0 .data : AT (_etext) { _sdata = .; *(.data .data.* .gnu.linkonce.d.*) . = ALIGN(4); *(.ramfunc); . = ALIGN(4); _edata = .; } > SRAM0 nichts, da dann die zu initialisierenden Daten und die Initialisierungsdaten aufeinander liegen. Kurzum, hinter dem Text müsste man (_edata -_sdata) Platz lassen. Der GNU Linker kennt aber meines Wissens keine Vorwärtsreferenz. Man muss explizit xxx Bytes frei lassen. Das geht natürlich einige Zeit gut. Aber entweder der Bereich ist zu gross, und man verschenkt noch mehr SRAM, oder er ist zu klein und der Linker meldet keinen Fehler und beim Programmlauf geht irgendetwas schief. Übersehe ich eine Möglichkeit?
> Kurzum, hinter dem Text müsste man (_edata -_sdata) Platz lassen. D. h. nochmals so viel Platz wie die initialisierten Daten benötigen? > Der GNU Linker kennt aber meines Wissens keine Vorwärtsreferenz. Was ist eine Vorwärtsreferenz? > Man muss explizit xxx Bytes frei lassen. xxx im Sinne einer allgemeinen Konstanten oder der jeweiligen tatsächlich benötigten Größe? Zeig doch mal Deine Ausgangsbasis (normales Linker script) und die aktuelle Version für "Run in RAM". Und das Trampolin. Ist das Trampolin in Assembler geschrieben? Bzw. benötigt es RAM?
Roland H. schrieb: >> Kurzum, hinter dem Text müsste man (_edata -_sdata) Platz lassen. > > D. h. nochmals so viel Platz wie die initialisierten Daten benötigen? > Ja. >> Der GNU Linker kennt aber meines Wissens keine Vorwärtsreferenz. > > Was ist eine Vorwärtsreferenz? Ich wuerde gerne .text:{ *(.text .text.* .gnu.linkonce.t.*) *(.rodata .rodata* .gnu.linkonce.r.*) .etext = .; } > SRAM0 .data : AT (_etext) { >>> . + = _edata - _sdata; _sdata = .; *(.data .data.* .gnu.linkonce.d.*) . = ALIGN(4); *(.ramfunc); . = ALIGN(4); _edata = .; } > SRAM0 schreiben. Wenn der Linker aber zu der Zeile mit >>> kommt, dann ist weder _sdata noch _edata bekannt. Das habe ich als Vorwärtsreferenz bezeichnet. >> Man muss explizit xxx Bytes frei lassen. > > xxx im Sinne einer allgemeinen Konstanten oder der jeweiligen > tatsächlich benötigten Größe? > xxx im Sinne einer Zahl, von der man meint, das genugend Platz für die Variablen Daten bleibt. Ich habe 0x1000 genommen, bei der F2/F4 Familie mit 128(+) k Ram muss man ja nicht knausern. > Zeig doch mal Deine Ausgangsbasis (normales Linker script) und die > aktuelle Version für "Run in RAM". Das angehängte Linkerskipt stm32f10x_ram.ld ist STM32 generisch. Vorher gibt es ein Devicespezifisches Linkerskript. > Und das Trampolin. Auch angehängt. > Ist das Trampolin in Assembler geschrieben? Nein >Bzw. benötigt es RAM? Nein.
Wenn ich es richtig verstanden haben, dann willst Du so etwas
1 | .data : AT (_etext) |
2 | { |
3 | . + = xxx; |
4 | _sdata = .; |
5 | *(.data .data.* .gnu.linkonce.d.*) |
6 | . = ALIGN(4); |
7 | *(.ramfunc); |
8 | . = ALIGN(4); |
9 | _edata = .; |
10 | } > SRAM0 |
um den Platz freizuhalten, so dass zwischen den Initial-Werten und den eigentlichen Variablen unterschieden werden kann. Wie wäre es damit, zwei Linker-Läufe anzusetzen? Im ersten Lauf bekommt xxx einen bel. Wert, nach dem Lauf die Differenz berechnen, im zweiten Linker-Lauf mittels Kommandozeilenparameter den Wert xxx ins Linker-Script geben (oder mit einem 2. Linker-Script und include). Hab's noch nie probiert, einfach als Idee.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.