Hallo,
für die Programmierung eines STM32 verwende ich Atollic Truestudio, also
GCC drunterliegend und bastle mir gerade die Option Bytes direkt ins ELF
bzw. HEX File.
Hierfür habe ich das Linkerscript wie folgt modifiziert:
Ob das ganze nun denn auch so die gewünschte Wirkung erzielt muss ich
noch ausprobieren, was mich gerade interessiert ist, warum ich die
Variablen zusätzlich mit dem Attribut 'used' belegen muss, wenn ich doch
im Linkerscript die Sektionen schon mit KEEP markiert habe - ich bin da
nun einfach neugierig :)
Kann's mir jemand erklären?
Gruß Ralf
Ralf schrieb:> was mich gerade interessiert ist, warum ich die Variablen> zusätzlich mit dem Attribut 'used' belegen muss, wenn ich doch> im Linkerscript die Sektionen schon mit KEEP markiert habe
Davon weiß GCC aber nix.
"used" wirkt auf Compiler-Ebene.
"KEEP" wirkt auf Linker-Ebene.
Wenn globale Optimierungen aktiviert sind, dann kann GCC nicht
referenzierte Objekte / Funktionen entsorgen. Gleiches gilt auch auf
Ebene einer Compilation Unit, wenn der Compiler die Nichtreferenzierung
auf dieser Ebene nachweisen kann.
Der Linker arbeitet nur mit Symbolen und Input- und Output-Sections.
Wenn aus einer bestimmten Input-Section keine Symbole referenziert
werden, dann kann der Linker diese Section mit --gc-sections entsorgen
falls nicht mit KEEP markiert. Dabei gilt des Entry-Symbol als
referenziert.
In deinem Falle braucht's auf Linker-Ebene ein KEEP und auf
Compiler-Ebene
Ah, okay. Dann hab ich ja die richtige Lösung verwendet.
>> In deinem Falle braucht's auf Linker-Ebene ein KEEP und auf>> Compiler-Ebene>> __attribute__((_used_,__externally_visible__))
Das muss ich mal probieren, ob ich das zweimalige _attribute_
wegbekomme.
Besten Dank.
Ralf
Ist das nicht ein prima use case für das (anscheinend in sich
widersprüchliche)
1
constvolatile
???
Sollte eigentlich den Compiler ("ich habe nicht vor, da was dran zu
ändern, aber möglicherweise jemand anders") davon abhalten, die Variable
zu entsorgen.
Ralf schrieb:> für die Programmierung eines STM32 verwende ich Atollic Truestudio, also> GCC drunterliegend und bastle mir gerade die Option Bytes direkt ins ELF> bzw. HEX File.
Das ist zwar an sich eine schöne Idee, es ist schon ärgerlich, dass die
Option-Bytes immer "nebenher" laufen. Allerdings wird das nicht so
einfach zum Ziel führen:
Die Option-Bytes werden nicht über die "normale" Flash-Programmierung
beschrieben, sondern mittels Schreiben in die Flash-Option-**Register**.
Dabei werden die "echten" Flash-Zellen zuerst gelöscht und danach die
"aufgebohrten" Werte (d .h. zusätzlich auch noch die invertierten Werte)
in die Flash-Zellen geschrieben.
Das Konzept mit den Option-Bytes im Elf-File würde nur funktionieren,
wenn der Flash-Programmer die Option-Bytes da herausfischt und sie dann
in die entsprechenden Register schreibt. Müsste man für jeden Chip
individuell einbauen ...
Bei der Kinetis-Familie ist das etwas schöner gelöst, hat aber auch
wieder unschöne Seiteneffekte, da ein Erase dann gleich alle
Option-Bytes mit löscht.
A. B. schrieb:> Die Option-Bytes werden nicht über die "normale" Flash-Programmierung> beschrieben, sondern mittels Schreiben in die Flash-Option-**Register**.> Das Konzept mit den Option-Bytes im Elf-File würde nur funktionieren,> wenn der Flash-Programmer die Option-Bytes da herausfischt und sie dann> in die entsprechenden Register schreibt.
Macht der eingebaute UART-Bootloader in den STM32 nicht genau das?
A. B. schrieb:> Das Konzept mit den Option-Bytes im Elf-File würde nur funktionieren,> wenn der Flash-Programmer die Option-Bytes da herausfischt und sie dann> in die entsprechenden Register schreibt. Müsste man für jeden Chip> individuell einbauen ...
Eine Alternative (falls er sie nicht wie ein Kinetis beim Reset
automatisch aus dem Flash liest) ist es am Anfang der Main (oder im
Startup oder wo auch immer es gut passt) den Zustand der Option-Bytes zu
prüfen und sie ggf. dann auf die dafür vorgesehene Weise zu setzen. Dann
muss man sein Gerät halt mindestens einmal einschalten bevor man es
verkauft. Für den Debugbuild muss man diese Routine halt deaktivieren.
Ralf schrieb:> Ob das ganze nun denn auch so die gewünschte Wirkung erzielt muss ich> noch ausprobieren, was mich gerade interessiert ist, warum ich die> Variablen zusätzlich mit dem Attribut 'used' belegen muss, wenn ich doch> im Linkerscript die Sektionen schon mit KEEP markiert habe - ich bin da> nun einfach neugierig :)
Ich habe noch nicht ganz verstanden, was du mit der Variable erreichen
willst. Wenn der Compiler die aber wegoptimiert, dann war sie entweder
überflüssig (also warum dann erzwingen) oder nicht richtig als volatile
gekennzeichnet und der Compiler hat es wegoptimiert. Bei zweitem bin ich
mir nicht sicher, ob das used reicht, wenn der Compiler dann trotzdem
den Code zum setzen löscht.
M.K. B. schrieb:> Ich habe noch nicht ganz verstanden, was du mit der Variable erreichen> willst.
Er will daß diese Konstante genau an der Stelle im Flash zu liegen kommt
wo diese Werte die gewünschte Wirkung erzielen. Bei einigen Controllern,
zum Beispiel bei den oben kurz erwähnten Kinetis-Controllern gibts 16
Bytes im Flash bei Adresse 0x400 kurz hinter der Vektortabelle damit
werden die Lockbits gesetzt und noch ein paar andere Optionen. Bei jeden
Einschalten wird das als erstes gelesen und die Flash Security und noch
ein paar andere Sachen entsprechend gesetzt. So ähnlich wie die Fuses
beim AVR (die man dort allerdings separat setzen muss), nur liegen sie
in dem Fall als ganz normale Bits im Programmflash und man kann dann
direkt ins .bin reinbacken und die werden dann immer gleich in einem
Rutsch vollautomatisch an die richtige Stelle geflasht.
Allerdings ist der Einwand des anderen Users weiter oben nicht
unberechtigt, es mag durchaus sein daß das bei STM32 nicht ganz so
simpel funktioniert wie beim Kinetis, STM32 sind in jeder Hinsicht
weitaus komplizierter zu handhaben und alles ist intern deutlich
verschwurbelter organisiert als bei den simplen Kinetis-Controllern wo
alles ziemlich direkt und geradeaus ist, von STM32 kommt der Mythos daß
"ARM kompliziert" sei. Wer den ersten Kontakt allerdings mit einem
Kinetis erlebt hat kann darüber nur den Kopf schütteln, aber lassen wir
das, ich schweife ab...
> bin ich> mir nicht sicher, ob das used reicht,
KEEP und used reicht, das funktioniert wie dokumentiert. Auch für andere
Zwecke ist das verwendbar, zum Beispiel eine Konfiguration des
Bootloaders die beim Flashen des Bootloaders einmalig eingebrannt wird
(zum Beispiel für eine I2C-Adresse oder eine Seriennummer oder
dergleichen) und die später auch von der Anwendung gelesen werden kann
schon beim Flashen der Bootloader.bin an eine fixe Stelle ins Flash zu
legen.