Forum: Mikrocontroller und Digitale Elektronik AVR Problem mit -nostartfiles


von Stored B. (Firma: drx) (umbrecht)


Angehängte Dateien:

Lesenswert?

Hallo,

mir ist aufgefallen, wenn ich die Option -nostartfiles in Atmel Studio 7
nutze, dass Strings die ich über Uart senden möchte nicht Ausgegeben
werden. Grund dafür ist, dass das erzeugte Programm den Text aus dem
Flash nicht ins RAM kopiert. Die Funktion __do_copy_data wird zwar
eingefügt aber nie Aufgerufen. Warum ist das so? Selbes Phänomen ist mir
auch bei dem Attiny2313 und ATmega32 aufgefallen.
Erstelle ich mir eine eigene __do_copy_data werden die Strings korrekt
ausgegeben.

Eine Vermutung von mir wäre, dass ich mit dem falschen Sektor arbeite,
allerdings habe ich dazu nicht viel gefunden.
1
__attribute__((section(".ctors"))) void boot(void)

Ich füge mal das Programm mit an. Mein Ziel wäre quasi das nur die
Interrupt Tabelle nicht eingefügt wird, dafür aber die
Stackinitialisierung und das Kopieren der Texte ins RAM.

Danke für eure Antworten oder Hilfe.

BG
Umbrecht

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Mit -nostartfiles fehlt der Start-Code der avr-libc (crt*.o).

Was willst du denn erreichen?

von Stored B. (Firma: drx) (umbrecht)


Lesenswert?

Johann L. schrieb:
> Was willst du denn erreichen?

Stored B. schrieb:
> Mein Ziel wäre quasi das nur die
> Interrupt Tabelle nicht eingefügt wird, dafür aber die
> Stackinitialisierung und das Kopieren der Texte ins RAM.



Johann L. schrieb:
> Mit -nostartfiles fehlt der Start-Code der avr-libc (crt*.o).

Nicht ganz. Ein Teil davon (__do_copy_data) befindet sich trotzdem im 
Programm, wird aber nicht aufgerufen.

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

In dem Fall schreib ein eigenes Startfile, am einfachsten mit dem crt*.S 
der avr-libc als Vorlage.

https://svn.savannah.gnu.org/viewvc/avr-libc/trunk/avr-libc/crt1/

von Stored B. (Firma: drx) (umbrecht)


Lesenswert?

Ich habe es bisher auch so ähnlich gemacht, ist aber immer nervig jedes 
mal die __do_copy_data Funktion zu ändern sobald Daten dazugekommen 
sind, hätte das gerne Automatisch.

Danke für den Link, ich schau mir mal an ob ich das zu meinen wünschen 
anpassen kann.

von Stored B. (Firma: drx) (umbrecht)


Lesenswert?

Habe gefunden was mir hilft, mit den Marcos lo8(__data_end) usw. kann 
ich das recht schön Automatisch handhaben. Danke.

BG

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Kann man (wenn ja wie) in gcc eine C-Funktion schreiben, die vor main() 
als eigene Init-Funktion aufgerufen wird?

(Oder) muss ich immer eigene crt*.S haben und von dort meine Init 
C-Funktion aufrufen.

von Andreas M. (amesser)


Lesenswert?

Wenn Du den String einfach direkt aus dem Flash liest, dann brauchst du 
überhaupt keine Kopierroutine sondern kannst den String direkt aus den 
Flash raus verwenden. Das spart dann auch RAM.

https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Flash_mit_PROGMEM_und_pgm_read

Was hier passiert, ist das der (Konstante)  String im "rodata" segment 
definiert wird. Der Initialwert dafür liegt im Flash und muss beim 
Booten erst aus dem Flash in den Ram übertragen werden. Wenn das halt 
fehlt...

von Stored B. (Firma: drx) (umbrecht)


Lesenswert?

Apollo M. schrieb:
> Kann man (wenn ja wie) in gcc eine C-Funktion schreiben, die vor main()
> als eigene Init-Funktion aufgerufen wird?

Grundsätzlich so:
1
__attribute__((section(".init2"))) void boot(void)

Hier wird das ganze recht schön beschrieben:
https://rn-wissen.de/wiki/index.php/Avr-gcc/Interna

von Peter D. (peda)


Lesenswert?

Stored B. schrieb:
> Mein Ziel wäre quasi das nur die
> Interrupt Tabelle nicht eingefügt wird

Ehrlich, der ganze Aufriß nur wegen 0,3% mehr Flash?

von Stored B. (Firma: drx) (umbrecht)


Lesenswert?

Peter D. schrieb:
> Ehrlich, der ganze Aufriß nur wegen 0,3% mehr Flash?

Klar, fehlt Speicher, muss ein größerer Controller her.
Aber wenn ich mein Auto sauber mache, dann komplett, nützt ja nichts 
wenn eine leere Dose noch drin liegt.

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Stored B. schrieb:
> __attribute__((section(".init2"))) void boot(void)

Danke für den Link!
Habe es ausprobiert und ich denke da muss noch ein noreturn dazu
1
 __attribute__((section(".init1"), noreturn)) void boot()

Wenn anstatt .init2 im .init1 Segment plaziert, dann wird die Funktion 
zu allererst ausgeführt.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Apollo M. schrieb:
> Kann man (wenn ja wie) in gcc eine C-Funktion schreiben, die vor main()
> als eigene Init-Funktion aufgerufen wird?
1
// Installiert die my_init() Prozedur in den Start-Bereich 5,
2
// so dass sie automatisch vor main() ausgeführt wird.
3
void my_init() __attribute__ ((naked))  __attribute__ ((section (".init5")));
4
5
// Initialisiert ... was auch immer
6
void my_init() 
7
{
8
   ...
9
}

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Stefan ⛄ F. schrieb:
> _attribute_ ((naked))

gefällt mir noch besser als noreturn!

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.