Morgen,
gibt es beim gcc (insbesondere avr-gcc) eine Möglichkeit, die
main-Funktion umzubenennen?
Das könnte sich evtl als nützlich erweisen für das was ich gerade
probier :-)
Mit Umbenennen meine ich dass, nach Abarbeitung des StartUp-Codes eben
nicht main() sondern z.B. myMain() angesprungen wird.
Aber ich fürchte ja, dieser Sprung ist fest in den StartUp-Code
codiert...
Was ich nicht will, bzw. nicht geht:
1) Mit Makros und #ifdefs zur Compilezeit zwischen zwei main()s
umschalten. Auserdem müsste dazu bestehender Code angefasst werden.
2) Der Parameter -e des gcc-Linkers ist mir bekannt. Damit kann ich den
Einsprungspunkt meines Programmes festlegen. Aber so wie ich das
verstehe ist dieser standardmäsig _start, also der Beginn des
StartUp-Codes. Ändere ich diesen also, so wird mein Prozessor nicht
initialisiert und mein Programm dementsprechend nicht laufen (kein
Stack, keine globalen Variablen etc...)
Gibts da was?
Grüße!
probiere mal hier im makefile:
# Target file name (without extension).
TARGET = main
Ich habe das jetzt nicht ausprobiert, aber hatte mal einen
Bastel-Bausatz, da hieß das 'test'
Ohne dein makefile zu kennen rate ich jetzt einfach mal:
TARGET ist in deinem makefile die Variable die den Namen des Executables
(und wahrscheinlich auch des Hex-Files) festlegt.
Danke für den Versuch, aber das ist sehr weit am Thema vorbei :-)
Ich denke nicht das das geht, zumindest nicht als Parameter für den GCC.
Denn der StartUp code kommt ja nicht vom Compieler sondern von der
Runtime (eine Lib?). Dort ist ja die Reihenfolge festgelegt.
Wenn du das ändern willst, musst du dir eine andere Runtime bauen und
diese als Startcode angeben.
Sean Goff schrieb:> Was spricht gegen> main()> {> Mymain();> }> ?> Kann auch sein dass ich deine Frage falsch verstanden hab.
Aber das kostet doch ein paar Bytes vom RAM. :-)
Tipp: Da man nie zurückspringen will kann man die "verloreren" Bytes ja
gefahrlos anderweitig wieder benutzen.
Sean Goff schrieb:> Was spricht gegen> main()> {> Mymain();> }> ?
Mein erster Beitrag, wo ich schrub:
>Was ich nicht will, bzw. nicht geht:>1) Mit Makros und #ifdefs zur Compilezeit zwischen zwei main()s>umschalten. Auserdem müsste dazu bestehender Code angefasst werden.
Ok, deine Lösung hat keine Makros, aber ich muss bestehenden Code
(nämlich die "richtige" main) umschreiben.
Alle darauffolgenden Antworten (goto etc.) bringen das selbe Problem mit
sich.
Und ja, ich denke auch nicht dass des als gcc Parameter geht, da eben
wahrscheinlich der StartUp-Code geändert werden muss.
Aber hätte ja sein können dass die gcc-Experten da mehr wissen :-)
Hermann-Josef schrieb:> und was ist mit dem Umschreiben der .init9-Section?
Das ist prinzipiell möglich. Aber dann muss ich noch eine zweite Version
des StartUp-Codes bereithalten und beim make-Aufruf gegen diese Version
linken.
Bzw. eben per -e Parameter in die _start dieses Alternativ-StartUp-Codes
springen.
Aber ich werde das mal weiter verfolgen, denn das geht schon sehr in die
Richtung die ich mir vorstelle.
Der Code soll nicht angefasst werden, lediglich der Compiler-Aufruf soll
steuern, ob main() oder myMain() aufgerufen wird.
Dann kann man sich auch bequem dafür ein extra Target im Makefile
anlegen.
Eigentlich geht das in Ordnung. Nachteil ist, bei einem Update der
Toolchain muss der Alternativ-StartUp-Code neu erstellt werden.
Am Bequemsten wär eben ein Linker-Flag, aber sowas gibts wohl nicht :/
le x. schrieb:> Am Bequemsten wär eben ein Linker-Flag, aber sowas gibts wohl nicht :/
oder man schreibt sich einen Patch. main wird doch auch nur
angesprungen, also braucht man nur die Sprungadresse auf deine mymain zu
ändern. Das sollte schon mit einem script und der lss Datei möglich
sein.
Die eigentliche Frage ist doch eher, warum braucht der TO das oder meint
es zu brauchen.
Ich wette es gibt ne bessere Lösung als ein alternatives (2.) main().
wenn schon makefile, dann würde ich im makefile zwischen zwei C-Files
umschalten, die zum jeweiligen Projekt gehören. Beide enthalten ihr
eigenes main(), aber nur eines der beiden wird compiliert und gelinkt,
abhängig vom Target.
le x. schrieb:> Der Code soll nicht angefasst werden, lediglich der Compiler-Aufruf soll> steuern, ob main() oder myMain() aufgerufen wird.
Du musst doch den Code nicht anfassen um das mit Makros zu lösen. Und
wie kommst du auf #ifdef?
# prog.c enthält "MyMain()":
avr-gcc -c -DMyMain=main prog.c
Udo Schmitt schrieb:> Die eigentliche Frage ist doch eher, warum braucht der TO das oder meint> es zu brauchen.> Ich wette es gibt ne bessere Lösung als ein alternatives (2.) main().
Jau. Würde mich auch interessieren. Vor allen Dingen, warum dazu der
Code nicht angefasst werden darf.
Denn eines haben diese Hintenrum-Lösungen alle gemeinsam. Zuerst hält
man sie für eine wahnsinnig tolle Idee. Nach 3 Wochen kennt sich keiner
mehr aus. Nach einem halben Jahr hat man den Trick schon längst wieder
vergessen. Und nach einem 3/4 Jahr verflucht man sich selber, weil man
bei der Reanalyse, was man da eigentlich gemacht hat, ums verrecken
nicht mehr drauf kommt, wie und warum das eigentlich funktioniert.
Um wieviel einfacher wäre ein #define gewesen, dass man im Code
kommentieren kann, so dass alles beisammen bleibt.
Udo Schmitt schrieb:> Die eigentliche Frage ist doch eher, warum braucht der TO das oder meint> es zu brauchen.> Ich wette es gibt ne bessere Lösung als ein alternatives (2.) main().
Jaja, immer die TOs die sich einbilden, irgendwas brauchen zu würden.
Vielleicht interessiert mich eher die akademische Natur der Sache?
Toolchain Internas, etc.
Aber OK:
Gegeben sei ein mittelgroßes Projekt (für ATmega-Verhältnisse :-)).
Dieses erstreckt sich über mehrere Module, von denen einige fertig sind,
manche sich aber auch noch in der Entwicklung befinden.
Manchmal will man vielleicht eine neue Funktion, einen Algorithmus, eine
Umrechnung schnell mal testen. Und zwar völlig spontan.
Nicht erst die Bedinungen herstellen die überhaupt notwendig sind damit
diese Funktion aufgerufen wird, oder warten bis irgendwelche Ereignisse
eintreten die diese Funktion triggern.
Kurz: Prozessor flashen, Funktion wird abgearbeitet. Schön wäre es, wenn
man dafür ein Target hätte, die dieses Feature bereitstellt. Dann ist es
ein Befehl in der Shell, oder ein Klick, je nach Vorlieben.
Nicht erst die main.c öffnen, irgendwas auskomentieren, Funktionsaufruf
einfügen usw. Kurz: nicht in Sourcen rumklauben die fertig sind.
Denn mal ehrlich, wer kennt es nicht? Du entwickelst, probierst rum,
kommentierst Dinge aus, verunstaltest existierenden Code. Und wenn dann
alles läuft wird garantiert nicht mehr aufgeräumt...
Ich sehe auch nicht das von KHB angesprochene Problem, das man den
Mechanismus dahinter "vergisst" und deswegen mit #defines arbeiten
sollte.
Ganz im Gegenteil: wenn jemand meine Sourcen durchsieht muss er sich
nicht erst fragen was denn da überall für Artefakte im Code
rumschwirren, welche seltsamen defines die main() umhüllen, wo denn
diese defines gesetzt werden und was noch notwendig ist um ein Feature
zu nutzen, das er nicht braucht.
Nein, ich muss nur ein Target aus dem MF löschen und alle Spuren meines
Workarounds sind verschwunden.
Auch wenn manchen die Fantasie vielleicht fehlt, wo hier der konkrete
Nutzen wäre: ich hätte einen, und zwar erheblich.
Leider wird sich nun die Diskussion in eine völlig andere Richtung als
meine ursprüngliche Frage entwickeln. Aber ich denke, ich hab meine
Antwort eh schon :-)
Viele Grüße!
le x. schrieb:> Jaja, immer die TOs die sich einbilden, irgendwas brauchen zu würden.
Die kennen halt alle Java, und setzen solche Annehmlichkeiten einfach
voraus.
Aber ganz ehrlich, bei Projekten in der Größe eines handelsüblichen
Bastler-AVR-Programms kann man sich ja nun problemlos angepasste Kopien
von main anlegen. Die sind dann schnell per Hand umbenannt, und genauso
schnell auch wieder gelöscht.
Mit #define und #if im Originalcode herumzufuhrwerken ist nicht die
Lösung.
Oliver
le x. schrieb:> Denn mal ehrlich, wer kennt es nicht? Du entwickelst, probierst rum,> kommentierst Dinge aus, verunstaltest existierenden Code. Und wenn dann> alles läuft wird garantiert nicht mehr aufgeräumt...
Kein Versionskontrollsystem?! Ich würde einfach meinen Testaufruf in die
main.c machen, diese aber dann nicht einchecken und nötigenfalls
zurücksetzen.
Alternativ ginge auch folgendes im Makefile:
> Mit #define und #if im Originalcode herumzufuhrwerken ist nicht die> Lösung.
Natürlich nicht. Das predige ich ja selbst schon seit Beginn an :-)
>> Kein Versionskontrollsystem?! Ich würde einfach meinen Testaufruf in die> main.c machen, diese aber dann nicht einchecken und nötigenfalls> zurücksetzen.
Doch natürlich, benutze hier git.
Klar geht das, aber ich wünsche mir halt immer noch irgendwie die
Ein-Klick-Lösung (respektive ein-Kommando).
Mir ist aber noch was gekommen, das werd ich so mal testen:
Ganz normal Kompilieren, aber vorm Linken mittels strip das Symbol
"main" aus der main.o entfernen.
Meine zu testende Funktion muss dann natürlich main() heißen oder von
einer dummy-main() aufgerufen werden, aber das ist noch tragbar, da sich
das alles innerhalb der aktuellen c-Datei abspielt. Evtl. kann man diese
Funktion kurz im Quelltext kennzeichnen, etwa so wie die avr-libc das
mittels ISR macht. Das Ganze kann man dann in einem Header verstecken.
Pack doch jede deiner main()-Funktionen, und nur diese, in verschiedene
C-Files. Das ergibt beim compilieren unterschiedliche Object-Files und
je nach Build-Target übergibst du dem Linker das entsprechende
Object-File.
le x. schrieb:> Kurz: Prozessor flashen, Funktion wird abgearbeitet. Schön wäre es, wenn> man dafür ein Target hätte, die dieses Feature bereitstellt. Dann ist es> ein Befehl in der Shell, oder ein Klick, je nach Vorlieben.
Dann schreibe doch gleich, dass Du so etwas haben willst. Stattdessen
führst Du alle Mitleser und -schreiber absichtlich in die Irre, indem Du
eine komplett andere Frage stellst.
Die Lösung ist nämlich viel, viel einfacher als sämtliche Basteleien mit
Präprozessordirektiven oder Eingriffen in den Startvorgang: man erstelle
einfach mehrere Quelltexte, in denen die entsprechenden
main()-Funktionen implementiert sind. Und im Makefile oder der IDE
konfiguriert man eben mehrere Targets, in denen die Kompilate der
unterschiedlichen Quelltexte angezogen werden. Fertig ist die Laube.
Informiere dich mal über "test driven development".
Schreibe dir halt für einzelne Funktionen und Module eigene Tests die
jeder ein main haben.
Die Tests kannst du dann bei jeder Änderung am Code wieder benutzen,
bzw. bei einer Portierung mit portieren und kannst damit sofort das
portierte testen.
Braucht nur etwas Organisation und schon kannst du die gesamte Frickelei
weglassen.
le x. schrieb:> Jaja, immer die TOs die sich einbilden, irgendwas brauchen zu würden.
Nein, immer die TOs, die meinen ihr kruder Ansatz wäre der einzige Weg.
Andreas Schweigstill schrieb:> Dann schreibe doch gleich, dass Du so etwas haben willst. Stattdessen> führst Du alle Mitleser und -schreiber absichtlich in die Irre, indem Du> eine komplett andere Frage stellst.
Nö. Ich habe genau die Frage gestellt, die mich interessiert hat.
"Kann man mit gcc eine andere Funktion außer main() als erste C-Funktion
anspringen?"
Eine Antwort darauf hab ich zwar nicht bekommen, kann mir aber
mittlerweile selbst zusammenreimen dass es erstmal nicht geht, da der
Sprung hartcodiert im StartUp-File liegt.
> man erstelle einfach mehrere Quelltexte, in denen die entsprechenden> main()-Funktionen implementiert sind. Und im Makefile oder der IDE> konfiguriert man eben mehrere Targets, in denen die Kompilate der> unterschiedlichen Quelltexte angezogen werden.
Viel, viiieel mehr Aufwand als wenn man die main() ändern könnte.
Mehrere Quelltexte mit einer main()? Und dann noch mehrere Targets? Für
was? Brauch ich nicht, für das was ich will. Auch viel mehr Arbeit als
meine Methode mit strip.
Genauso wie der Beitrag von Udo Schmitt.
"test driven development"? Module Tests? Wo hab ich denn sowas
geschrieben?
Und dabei wollt ich doch nur kurz und unkompliziert z.B. meine
atoi()-Implementierung testen...
Also, ohne jetzt unfreundlich klingen zu wollen:
Genau deswegen hab ich nicht geschrieben was ich vorhabe. Ist klar dass
es für jedes Problem 1000 mögliche Lösungen gibt. Und leider wird in
meine Beschreibung meines Vorhabens was ganz anderes hineininterpretiert
als ich vorhabe. Siehe Udo Schmitt und seine Module Tests. Der nächste
schlägt mir dann vor, meine Testvektoren nicht mit Matlab/Simulink
sondern mit Tool X zu generieren, weil das ja viel besser geht. Nur wo
hab ich sowas gefragt?
Genau deswegen formuliere ich meine Frage kurz und knapp und eindeutig
beantwortbar.
Ich werde meine Methode heut mal Testen und dann evtl. berichten. Wenn
noch was kommt freu ich mich, aber eigentlich seh ich den Thread als
gelaufen an, wir sind jetzt im Stadium "Diskussion und Wortklauberei"
angekommen :-)
Hm, ich könnt das ganze ja offiziell machen und einen 3.-Reich-Vergleich
bringen, dann weiß auch jeder dass es vorbei ist :-)
Viele Grüße!
lex schrieb:>> man erstelle einfach mehrere Quelltexte, in denen die entsprechenden>> main()-Funktionen implementiert sind. Und im Makefile oder der IDE>> konfiguriert man eben mehrere Targets, in denen die Kompilate der>> unterschiedlichen Quelltexte angezogen werden.>> Viel, viiieel mehr Aufwand als wenn man die main() ändern könnte.> Mehrere Quelltexte mit einer main()? Und dann noch mehrere Targets? Für> was? Brauch ich nicht, für das was ich will. Auch viel mehr Arbeit als> meine Methode mit strip.
Aber straight forward und wäre schon längst fertig, wenn du um 13:00
angefangen hättest.
le x. schrieb:> Nicht erst die main.c öffnen, irgendwas auskomentieren, Funktionsaufruf> einfügen usw. Kurz: nicht in Sourcen rumklauben die fertig sind.
Darum eigene Testprogramme
lex schrieb:> Module Tests? Wo hab ich denn sowas geschrieben?
Gar nicht, ich bin idealistischerweise davon ausgegangen, daß du bereit
bist was neues zu lernen.
lex schrieb:> Ist klar dass es für jedes Problem 1000 mögliche Lösungen gibt.
Gute und weniger gute, du scheinst dich für weniger gute zu entscheiden.
Viel Spass damit solange du Software nicht mal professionell entwickeln
musst.
Würdest du denn beim Testen gerne angeben können, welche Funktion nun
anstelle der main() angesprungen wird, oder soll es einfach quasi eine
main2() Funktion geben, die immer die selbe ist?
lex schrieb:> Und dabei wollt ich doch nur kurz und unkompliziert z.B. meine> atoi()-Implementierung testen...
Diese atoi() Funktion wird ja vemutlich Parameter und Rückgabewert haben
(und auch wenn nicht, es könnte mal eine Funktion geben, die du testen
möchtest, die Parameter und Rückgabewert haben), oder? Dann bringt dir
das direkte Anspringen dieser Funktion ja nicht viel, da du dann weder
Parameter übergeben, noch den Rückgabewert überprüfen kannst.
Also müsstest du für jede zu testende Funktion auch eine eigene
main()-Funktion machen, die dann die zu testende Funktion mit diversen
Parametern auf korrekte Arbeitsweise überprüft (was ja wie schon erwähnt
Richtung Modultests geht).
Oder sollen deine zu testenden Funktionen immer nur void foo(void)
Funktionen ohne Parameter und Rückgabewert sein?
Haja, ich wollt eigentlich nichts mehr dazu schreiben, aber wieso nicht,
ist eh schon egal :-)
> Gar nicht, ich bin idealistischerweise davon ausgegangen, daß du bereit> bist was neues zu lernen.
Module Tests kenn ich. Brauch ich nicht, zumindest nicht daheim im
Bastelkeller. Was neues lernen? Siehst, du interpretierst schon wieder
viel zu viel. Du triffst annahmen was ich weiß und was nicht, und was
ich brauchen könnte.
> Gute und weniger gute, du scheinst dich für weniger gute zu entscheiden.
Hm du leidest am selben Syndrom was du mir vorwirfst: Zu denken der
eigene krude Ansatz wär der Beste Weg.
> Viel Spass damit solange du Software nicht mal professionell entwickeln> musst.
Tu ich schon.
Soll ich dir verraten, in welche Fahrzeuge du zukünftig lieber nicht
mehr einsteigen solltest? Ne, ich lass dich im Ungewissen :-)
Schönen Tag noch zusammen
lex schrieb:> Nö. Ich habe genau die Frage gestellt, die mich interessiert hat.> "Kann man mit gcc eine andere Funktion außer main() als erste C-Funktion> anspringen?"> Eine Antwort darauf hab ich zwar nicht bekommen, kann mir aber> mittlerweile selbst zusammenreimen dass es erstmal nicht geht, da der> Sprung hartcodiert im StartUp-File liegt.
Geht nicht gibts nicht. RTFM.
Aus .init8 kannst du in dein selbsternanntes main springen.
Oliver
lex schrieb:> Kann man mit gcc eine andere Funktion außer main() als erste C-Funktion> anspringen?
Lege die Funktion per section Attribut nach .init8 und gut is.
Udo Schmitt schrieb:> Die eigentliche Frage ist doch eher, warum braucht der TO das oder meint> es zu brauchen.
Genau so ist es.
> Ich wette es gibt ne bessere Lösung als ein alternatives (2.) main().
Da verwett ich meinen A... drauf ;-)
lex schrieb:> Soll ich dir verraten, in welche Fahrzeuge du zukünftig lieber nicht> mehr einsteigen solltest?
Ich steige nur in Autos die mindestens schon 3 Jahre im Markt sind. Bis
dahin haben deine Kollegen deine Fehler gefunden :-)
Udo Schmitt schrieb:> le x. schrieb:>> Jaja, immer die TOs die sich einbilden, irgendwas brauchen zu würden.> Nein, immer die TOs, die meinen ihr kruder Ansatz wäre der einzige Weg.
Ihre Anzahl ist Legion.
So wie der Kollege, der selber ein Faxgerät entwickeln will, weil ihm
andere Lösungen zu teuer sind. Mann Mann Mann...
Udo Schmitt schrieb:> Ich steige nur in Autos die mindestens schon 3 Jahre im Markt sind. Bis> dahin haben deine Kollegen deine Fehler gefunden :-)
Owned. :)
Morgen zusammen,
lustig, dass hier manche gleich persönlich werden. Naja was solls.
Dieses Forum hat mir schon soviele Stunden Popcornkino beschert, da geb
ich gerne auch mal welches zurück :-)
An den Rest dens interessiert: dank Johann konnte ich gestern noch bisl
was zusammenschustern, und meine Lösung macht genau das was es soll.
Bin schon sehr zufrieden, auch wenn ich noch nicht alles umgesetzt habe.
Vielleicht wird ja auch dem einen oder anderen klar, wieso ich die
ursprüngliche Frage gestellt hab.
Was momentan geht:
Ich verwende eine leicht modifizierte Version des AVR Simulators
"avrtest". Wenn ich im Code gewisse Marken setze und das Executable dann
durch den Simulator jage krieg ich verschiedene Infos, z.B. die Takte
die ein Block oder eine Funktion benötigt. Sehr interessant vor allem
für ISRs.
Anwendung:
Gegeben sei ein Projekt mit mehreren Modulen. Ich arbeite gerade an
einer Funktion foo() in irgendeiner c-Datei.
1
voidfoo(void)
2
{
3
...
4
}
Will ich mal eben die Laufzeit dieser Funktion messen so ersetz ich kurz
den Funktionskopf:
1
CYCLE_COUNT_FUNC(foo)
2
{
3
...
4
}
Diese Schreibweise ist ja auch aus der avr-libc bekannt, für ISRs.
Danach tippe ich auf der Kommandozeile
1
makeavrtest
oder drücke den passenden Knopf auf meiner IDE.
Dadurch erhalte ich eine Ausgabe, ungefähr:
1
functioncyclecount:123
Find ich schon sehr praktisch. Vor allem unter Linux, wo es kein AVR
Studio zur Simulation gibt (nein, simulavr kommt da leider nicht ran).
Ich wüsst auch keine Möglichkeit, so eine Messung schneller
durchzuführen. Vor allem, ohne in verschiedenen c-Dateien
rumzukommentieren oder Aufrufe zu setzen/ändern. Denn je nach Projekt
müssen ja auch Vorbedingungen hergestellt werden, die zum
Funktionsaufruf führen. Funktioniert übrigens auch mit ISRs. Ich kann
mein Zeugs also völlig losgelöst vom restlichen Projekt kurz
analysieren.
So, nächstes Problem:
Ich arbeite an einer Funktion die Parameter übergeben bekommt:
1
char*myItoa(intvalue,char*str,intbase);
Um diese Funktion zu testen muss sie irgendwie bespaßt werden. Auserdem
ist zu erwarten dass unterschiedliche Aufrufe auch unterschiedliche
Laufzeiten ergeben.
Zugegeben, das kann und werde ich noch bischen eleganter hinter Makros
verstecken, aber momentan kann ich so vorgehen:
Ich muss mir (leider noch) eine kleine Helferfunktion schreiben. Dank
Makros aber auch nicht so wild.
1
CYCLE_COUNT_MAIN
2
{
3
CYCLE_COUNT_BLOCK
4
{
5
myItoa(123,buf,8);
6
}
7
}
Und erhalte ebenso meine Ausgabe, inklusiv Kosten für den Aufruf.
Zugegeben, hier muss ich schaun wie man das noch abkürzen könnt.
Nach getaner Arbeit wird dieses Konstrukt wieder entfernt.
Ich muss sagen, mir persönlich hat das gestern schon sehr geholfen, die
ISR meiner BCM zu optimieren. Weil mich momentan hauptsächlich
Laufzeiten interessieren habe ich bisher auch nur die Makros für die
Anbindung an avrtest umgesetzt.
Wer solche Probleme nicht hat, - OK.
Aber ich wüsst jetzt nicht wie man sowas geschickter hätte lösen können.
Ich muss nicht in anderen Sourcefiles rumklabustern, keinen Code umher
copy&pasten, keine Vorbedingungen für Simulatoren herstellen und habe
keine Target-Orgien im makefile.
Mir persönlich ging es darum, so wenig wie möglich anfassen zu müssen.
Die Messung soll wirklich ruck-zuck gehen und kein großes Überlegen
erfordern: "Hm, wo wird diese Funktion aufgerufen, wann passiert das,
was muss ich vorher eingeben?".
Viele Grüße
Doofe Frage, aber kann ich zum Takte einer ISR zählen nicht ziemlich
einfach das Assembler-Listing auswerten lassen?
Ohne das Programm zu zerteilen usw.?
Wenn das eine "klassische" ISR ist (rein , Flag setzen, raus), dann ja.
Wenn allerdings da drin was ernsthaftes passiert, eher nicht (zumindest
nicht einfach)
Oliver
Oliver schrieb:> Wenn das eine "klassische" ISR ist (rein , Flag setzen, raus),> dann ja.> Wenn allerdings da drin was ernsthaftes passiert, eher nicht (zumindest> nicht einfach)>> Oliver
Globale Variablen müssen natürlich bespaßt werden.
D.h. ich muss sie auf den Wert initialisieren der mich in den zu
testenden Pfad führt. Das musst aber immer, auch im Simulator.
Und ich weiß, dass meine ISR genau diesen Pfad durchlaufen wird, den ich
vorgebe.
lex schrieb:> Nö. Ich habe genau die Frage gestellt, die mich interessiert hat.> "Kann man mit gcc eine andere Funktion außer main() als erste C-Funktion> anspringen?"
Wenn du C++ nimmst, geht das dort direkt mit Sprachmitteln. Dort kann
man Klassen definieren, und beim Instanziieren wird der Konstruktor
aufgerufen, oder man kann eine Variable anlegen und mit dem Returnwert
einer Funktion initialisieren. Bei globalen Objekten wird der Aufruf
dann vor main() gemacht.
Und in GNU-C gibt's auch attribute constructor, mit dem man Funktionen
vor main() ausführen kann. Diese Constructors werden zum Zeitpunkt
ausgeführt wie statische C++ Konstruktoren auch.
Danke euch beiden, gibt ja doch einiges an Möglichkeiten.
Ich bin momentan ganz zufrieden so, läuft alles wie es soll! Ob ich
meine Funktion jetzt direkt nach .init8 lege oder als Konstruktor
deklariere (der dann im Prinzip auch in einer .init-Sektion liegt) ist
dann wohl Geschmacksache...
Nein, der Constructor liegt eben nicht in der .init-Section; er wird nur
von dort aus aufgerufen. Der Unterschied ist, dass er deshalb nicht
naked sein darf im Gegensatz zu "normalen" init-Funktionen, die naked
sein müssen und daher begrenzten Funktionsumfang haben. Für letztere
ist nur das Funktionieren von Inline-Assembler garantiert.