w.e. schrieb:> Was ist das für eine Parameterliste:(* const table_interrupt_vector[])> und warum steht direkt dahinter nochmal void in Klammer:(void)
Das ist keine Parameterliste sondern eine Deklaration eines
Arrays von Pointern, hier etwas spezieller eine Liste von
Adressen von auführbaren Funktionen. () wäre die Liste von
Übergabewerten für die Funktion(en) die bei dieser
Deklaration leer ist.
w.e. schrieb:> Brauche ich unbedingt ein C-TutotialQuelle schrieb:> Ja.
Bin ich auch der Meinung, jedoch wird man bei einem Lehrbuch
nicht zwingend und unmittelbar auf dieses seltener vorkommende
Konstrukt hingewiesen.
Könnt ihr etwas taugliches empfehlen? Ich fange ja nicht bei NULL in C
an, Grundlegende Dinge behersche ich, aber ab Zeiger hört es bei mir
auf. Es darf gerne ein Schnelltutorial sein.
jo mei schrieb:> Bin ich auch der Meinung, jedoch wird man bei einem Lehrbuch> nicht zwingend und unmittelbar auf dieses seltener vorkommende> Konstrukt hingewiesen.
Doch ganz sicher. Weil Zeiger und Arrays zu den Grundlagen der
Programmiersprache gehören.
Vielleicht kommst du mit einer Praxisorientierten Anleitung besser klar:
http://stefanfrings.de/mikrocontroller_buch/Einstieg%20in%20die%20Elektronik%20mit%20Mikrocontrollern%20-%20Band%201.pdf
Kapitel 4, und die Fortsetzung in band 2 Kapitel 11
Die bezieht sich allerdings auf AVR Mikrocontroller, anstatt auf STM32.
Wobei die Programmiersprache dort ja die gleiche ist.
> Grundlegende Dinge behersche ich, aber ab Zeiger hört es bei mir auf.
Dummerweise gehören Zeiger bei C zu den absoluten Grundlagen - bereits
im Hello-World sind sie zu finden.
Die Programmiersprache C (und noch mehr C++) enthält eine ganze Menge
Feinheiten, die man als Anfänger nicht wissen muss. Das Lesen von
fremden Quelltexten erfordert aber, dass du alles kennst, was dessen
Autor kennt und ist daher eher eine Aufgabe für erfahrene Entwickler.
> Ein Array von Funktionspointern sicher nicht.
Ja, über die Zeile
1
void(*consttable_interrupt_vector[])(void)={...}
Musste ich gerade auch eine ganz Weile grübeln. So etwas sieht man nicht
jeden Tag.
Die Programmiersprachen C und C++ kommen von Professoren, die an
Universitäten lehren. Solche Professoren stehen auch auf
Selbstgeisselung mit Matheaufgaben. Aber da müssen wir durch.
Hier ist ein Artikel mit Hilfe zum lesen solcher Deklarationen:
https://www.mikrocontroller.net/articles/Deklarationen_in_C
Oder
https://www.ostc.de/c-declaration.pdf
Das gezeigte Stück Code ist etwas spezielles weil sehr hardwarenah. Da
muss der Compiler schon genau das produzieren was der Prozessor
erwartet. Wenn die Ausdrücke zu komplex werden kann man die aber auch
mit typedefs entschärfen. Hat eigentlich nix mit Geisselung zu tun.
Rolf M. schrieb:> Zum GCC gehört auch das Tool, das solche Sachen in Klartext> umwandelt.> Scheint bei mir allerdings einen Bug zu haben. Es gibt aus:declare ��F!V> as array of const pointer to function that expects (void) returning> void;> Der Name ist irgendwie kaputt gegangen.
Wollte ich auch grad posten. Bei mir geht's:
Üblicherweise wird das mit einem typedef gemacht, dann ist es viel
einfacher zu verstehen:
Typedef für den Funktionspointer, und dann halt ein Array von diesem
Typ.
Das ist so selten, dass die meisten nicht auf Anhieb wissen, wo welche
klammern hingehören.
w.e. schrieb:> Was ist das für eine Parameterliste:
Ganz einfach: Die µC der Cortex-Liga erwarten ab Reset, daß sie ab
Adresse 0 eine Tafel vorfinden. Die 2 allerersten Einträge sind der
Startwert für den Stackpointer und die Adresse des ersten Befehls, den
die CPU ausführen soll, also der Kaltstart.
Danach kommen die Adressen der diversen Interrupt- und
Exception-Handler.
Normalerweise schreibt man sowas in einer Assembler-Quelle und markiert
das betreffende Segment als absolut auf Adresse 0 zu linken.
Aber da die werten C-Programmierer ja eine abgrundtiefe Abscheu gegen
Assembler in jeglicher Form haben, sind die Hersteller darangegangen,
mit passenden Verrenkungen eben diese Adresstafel nebst Kaltstartcode in
C zu formulieren.
Und das Ergebnis siehst du gerade vor dir.
also zuerst in C:
Und nun ist der Startwert für den Stackpointer (hier0x20000800) eben
keine Funktionsangabe, sondern ein Wert, der so wie er ist in den SP
gehört. Das ist ein wenig anders als bei der klassischen Adressierung
bei ARM: dort werden ARM- und THUMB- Code auch im Aufruf unterschieden,
was man am gesetzten LSB erkennt. Daher die für dich verwirrende
Darstellung per Cast (void*)
Tja, das ist eigentlich alles zum Thema. Wahrscheinlich fragst du dich
irgendwann mal, was [WEAK] zu bedeuten hat, aber das ist nur ein
Nachbarthema zu diesem.
W.S.
> Aber da die werten C-Programmierer ja eine abgrundtiefe Abscheu> gegen Assembler in jeglicher Form haben, sind die Hersteller> darangegangen, mit passenden Verrenkungen eben diese Adresstafel> nebst Kaltstartcode in C zu formulieren.
Falsch! Weil der HW-Designer die Exception/Interrupt-Behandlung so
gebaut hat, daß die C/C++-Aufraukonventionen eingehalten werden, kann
man auf ASM-Verrenkungen verzichten.
W.S. schrieb:> Aber da die werten C-Programmierer ja eine abgrundtiefe Abscheu gegen> Assembler in jeglicher Form haben, sind die Hersteller darangegangen,> mit passenden Verrenkungen eben diese Adresstafel nebst Kaltstartcode in> C zu formulieren.
Mal wieder keine Ahnung von nichts, aber ne große Klappe und daher die
falschen Schlüsse gezogen.
Frag dich mal wieso der NVIC genau die Register sichert, die er sichert.
Hallo,
>> (void *)0x20000800,
Der Stern macht die Zahl zu einem Zeiger;
>> void
void bewirkt dass der Zeiger vom Type void ist.
Anmerkung:
Bei einem 8 Bit Mikrocontroller bewirkt ein "inc Zeiger" um 1 Byte.
Bei einem 32 Bit Mikro greift man mit "inc Zeiger" um 4 Positionen
weiter zu.
w.e. schrieb:> Ich fange ja nicht bei NULL in C> an, Grundlegende Dinge behersche ich, aber ab Zeiger hört es bei mir> auf.
Entschuldigung, aber das mit dem NULL und "keine Ahnung von pointern"
war leider ein ziemlicher Witz (den C-Programmierer verstehen).
max123 schrieb:>>> void> void bewirkt dass der Zeiger vom Type void ist.
Nein. Das ist dann der Typ „Zeiger auf void“
> Anmerkung:> Bei einem 8 Bit Mikrocontroller bewirkt ein "inc Zeiger" um 1 Byte.> Bei einem 32 Bit Mikro greift man mit "inc Zeiger" um 4 Positionen> weiter zu.
Nein, das ist großer Müll was du da schreibst.
Das Inkrement hängt vom Typ ab, auf den der Zeiger zeigt, nicht von
der Architektur.
Das Inkrement ist sizeof(*Zeiger)
Stefan ⛄ F. schrieb:> Die Programmiersprachen C und C++ kommen von Professoren, die an> Universitäten lehren. Solche Professoren stehen auch auf> Selbstgeisselung mit Matheaufgaben. Aber da müssen wir durch.
Müssen wir dieses Gesülze von dir jetzt eigentlich jedes Mal lesen?
Dennis Ritchie und Ken Thompson mögen zwar beide Akademiker sein, aber
es gibt einen guten Grund, weshalb sich C schnell zum
Industriestandard gemausert hat. Es wurde direkt zur Entwicklung von
Unix geschaffen. Es war kein typisches akademisches Hobbyprojekt.
Besorg dir endlich mal ordentliche Lektüre zu C und zu C++ und lies es!
Die meisten Konzepte in Programmiersprachen sind weder kompliziert, noch
haben sie den Zweck den Anwender zu ärgern. Aber gut, man muss es halt
auch zulassen. Eigentlich erschreckend, dass du trotzdem Tutorials für
Anfänger schreibst (auch wenn ich so etwas allgemein für sehr ehrbar
finde).
Stefan ⛄ F. schrieb:> Die Programmiersprachen C und C++ kommen von Professoren, die an> Universitäten lehren.
Zumindest auf C trifft dies nicht zu.
K&R haben C erstmal für sich selber geschrieben. Als Werkzeug für
Profis.
Und das ist es immer noch.
Dirk B. schrieb:> Stefan ⛄ F. schrieb:>> Die Programmiersprachen C und C++ kommen von Professoren, die an>> Universitäten lehren.>> Zumindest auf C trifft dies nicht zu.> K&R haben C erstmal für sich selber geschrieben. Als Werkzeug für> Profis.> Und das ist es immer noch.
Und Bjarne saß (später) auf einem Flur mit den/einem der beiden. Beide
Sprachen wurden von Programmierern gemacht.
Professorensprache ist z.B. Pascal.
Dirk B. schrieb:> Als Werkzeug für> Profis.> Und das ist es immer noch.
LOL!!!
Du beschreibst das Problem perfekt: C Programmierer glauben etwas
besseres zu sein; typische Selbstüberschätzung. ???
MaWin schrieb:> LOL!!!>> Du beschreibst das Problem perfekt: C Programmierer glauben etwas> besseres zu sein; typische Selbstüberschätzung. ???
Ne. Das bedeutet nur, dass man mit C viel Unsinn machen kann :)
Rolf M. schrieb:> Im übrigen ist der Code in C eigentlich so gar nicht erlaubt, auch wenn> er von so ziemlich jedem Compiler trotzdem akzeptiert wird.
Was genau ist da nicht erlaubt? Die C++-Kommentare? Sind seit C99 im
Standard. Ansonsten seh ich nix.
MaWin schrieb:> Du beschreibst das Problem perfekt: C Programmierer glauben etwas> besseres zu sein;
Nein. C ist in der Anwendung nicht so einfach, wie es der Sprachumfang
und die Verbreitung erscheinen läßt.
Man ist als Programmierer völlig ungeschützt unterwegs und kann so
ziemlich jeden Unsinn beim Compiler durchbekommen.
Und meine Aussage bedeutet auch nicht, dass jeder der in C programmiert
ein Profi ist.
Hermann K. schrieb:> Rolf M. schrieb:>> Im übrigen ist der Code in C eigentlich so gar nicht erlaubt, auch wenn>> er von so ziemlich jedem Compiler trotzdem akzeptiert wird.>> Was genau ist da nicht erlaubt? Die C++-Kommentare? Sind seit C99 im> Standard. Ansonsten seh ich nix.
Die Konvertierung eines void* in einen Funktionszeiger ist eigentlich
nicht vorgesehen, allerdings immerhin unter "portability issues" -
"common extensions" gelistet. Da aber auch nur, um das, worauf er zeigt,
aufrufen zu können, wie es z.B. oft beim dynamischen Nachladen von
Bibliotheken gemacht wird, oder um den Inhalt des Funktionscodes
betrachten zu können.
Rolf M. schrieb:> Hermann K. schrieb:>>>> Was genau ist da nicht erlaubt? Die C++-Kommentare? Sind seit C99 im>> Standard. Ansonsten seh ich nix.>> Die Konvertierung eines void* in einen Funktionszeiger ist eigentlich> nicht vorgesehen, allerdings immerhin unter "portability issues" -> "common extensions" gelistet. Da aber auch nur, um das, worauf er zeigt,> aufrufen zu können
Das passiert hier aber gar nicht. Der erste Tabelleneintrag ist ja
gerade kein Funktionspointer, sondern eine "nackte" Speicheradresse -
top of stack. Und dafür ist void* genau der richtige Typ.
Wenn man die komplette Tabelle als ein Array anlegen will, muß man
entweder den ersten nicht-Funktionszeiger casten oder die vielen
anderen. Zweckmäßigerweise hat man sich für den ersten Weg entschieden.
Die ganz saubere Variante wäre gewesen, den ersten Tabelleneintrag
abzutrennen und zwei Arrays direkt hintereinander zu plazieren. Aber man
muß ja nicht päpstlicher sein, als der Papst.
---schnipp---
Ganz allgemein zu dem Thread:
1. Ja, Funktionszeiger sind ein elementares Konzept in C. Deswegen
gehören die in ein Tutorial. Nicht in den ersten Teil, aber ein
Tutorial, das Funktionszeiger komplett unter den Tisch fallen läßt, ist
ein Fall für die Tonne.
2. Dieser Code (Vektortabelle und Startup) ist typischer write-once
Code. Den schreibt man^W irgend jemand genau einmal. Und dann nutzt man
den nur noch. Typischerweise ist der in einer Support-Library verborgen
(z.B. libopencm3). Oder die IDE generiert ihn, wenn man ein neues
Projekt anlegt. Es ist aber durchaus sinnvoll, den wenigstens einmal zu
sehen und zu verstehen.
3. Der Code wird in der Tat oft in Assembler geschrieben. Wenn man
Assembler lesen kann, ist das dann auch leichter lesbar als der
äquivalente C Code. Einfach deshalb, weil Tabellen dieser Art ein
typisches Ding von Assembler sind. Andererseits kann man ihn auch in C
schreiben. Die Sprache ist ja extra hardwarenah designed worden, um das
zu erlauben. Und wenn der Rest des Programms C ist, warum sollte man
dann für den Startup-Code zu Assembler wechseln?
Axel S. schrieb:> Das passiert hier aber gar nicht. Der erste Tabelleneintrag ist ja> gerade kein Funktionspointer, sondern eine "nackte" Speicheradresse -> top of stack. Und dafür ist void* genau der richtige Typ.
Die Tabelle ist ein Array aus Funktionszeigern. Damit ist auch das erste
Element ein Funktionszeiger.
> Die ganz saubere Variante wäre gewesen, den ersten Tabelleneintrag> abzutrennen und zwei Arrays direkt hintereinander zu plazieren. Aber man> muß ja nicht päpstlicher sein, als der Papst.
Für einen einzelnen Eintrag braucht man kein Array. Ich hätte eine
struct aus einem void* und einem Array aus Funktionspointern gemacht.
Gar nicht mal, um "päpstlich" zu sein, sondern weil ich es lesbarer
finde. Mich hat der Code, so wie er oben steht, erstmal verwirrt.
> Ganz allgemein zu dem Thread:>> 1. Ja, Funktionszeiger sind ein elementares Konzept in C. Deswegen> gehören die in ein Tutorial. Nicht in den ersten Teil, aber ein> Tutorial, das Funktionszeiger komplett unter den Tisch fallen läßt, ist> ein Fall für die Tonne.
Die kann man in einem Tutorial auch z.B. über die Funktion qsort() ganz
gut erklären. Da leuchtet einem da schnell ein.
Hier ist der Fall aber noch komplexer, da es sich um ein Array aus
Funktionszeigern handelt. Dass dieser Stackzeiger da auch mit drin ist,
erleichtert das Verständnis auch nicht gerade.
> Und wenn der Rest des Programms C ist, warum sollte man dann für den> Startup-Code zu Assembler wechseln?
Teile davon werden vermutlich so oder so in Assembler implementiert
werden müssen, weil man in C über z.B. Register gar nicht die nötige
Kontrolle hat.
Rolf M. schrieb:>> Und wenn der Rest des Programms C ist, warum sollte man dann für den>> Startup-Code zu Assembler wechseln?>> Teile davon werden vermutlich so oder so in Assembler implementiert> werden müssen, weil man in C über z.B. Register gar nicht die nötige> Kontrolle hat.
Gerade die Cortex-M Controller sind von ihrem Architekturaufbau so, dass
man den Startup-Code auch ausschließlich in C machen kann. Man muss
bspw. den Stackpointer nicht selbst initialisieren, sondern nur den
Init-wert an eine bestimmte Stelle der Vektortabelle legen. Der Core
lädt ihn automatisch. Genauso müssen z.B. für Interrupts keine
Assembler-Wrapper geschrieben werden, die die Register auf den Stack
pushen. Das macht der Cortex auch selbst. Somit ist eine komplette
Implementierung des Startup-Codes in C möglich.
Ich meine NXP lieferte mit seiner IDE für die LPC Controller
Startupcodes in C mit, wohingegen STM Assembler mitliefert.
Für andere CPU-Architekturen/Mikrocontroller ist es aber teils zwingend
notwendig ASM-Startupcodes zu schreiben.
Axel S. schrieb:> 3. Der Code wird in der Tat oft in Assembler geschrieben. Wenn man> Assembler lesen kann, ist das dann auch leichter lesbar als der> äquivalente C Code. Einfach deshalb, weil Tabellen dieser Art ein> typisches Ding von Assembler sind. Andererseits kann man ihn auch in C> schreiben. Die Sprache ist ja extra hardwarenah designed worden, um das> zu erlauben. Und wenn der Rest des Programms C ist, warum sollte man> dann für den Startup-Code zu Assembler wechseln?
Warum? Oder warum nicht?
Nun, gerade bei dieser Tafel gibt es ja mehrere Besonderheiten, die in C
eben zusätzliche Umstände machen:
1. Die Tafel darf nicht irgendwo hin gelinkt werden, sondern hat ganz
präzise auf einer bestimmten Adresse zu stehen. Das ist eigentlich
ausdrücklich eine Assembler-Angelegenheit, denn alle höheren
Programmiersprachen sind ja genau dazu angelegt, ihren Benutzer eben
nicht mit derartigen Basics zu belästigen.
Was das gerade bei µC und deren Hardware-Registern in C für Umstände
macht, sehen wir ja in den betreffenden Controller- .h Dateien. Ja, es
geht, aber es ist ein umständliches Konstrukt für C.
2. Die Tafel muß ja auch mit Einträgen gefüllt werden, die man nicht
generell voraussehen kann. Deshalb muß jeder Eintrag mit einem
Default-Handler versehen werden, der aber dann, wenn man im Projekt
einen echten Handler hat, durch selbigen ersetzt werden muß. Daher das
Konstrukt mit dem "weak"-Attribut, das dann der Linker berücksichtigt.
Aber auch dieses ist so eigentlich nicht in C vorgesehen.
Und warum sollte man partout mit Krampf einen Startup in C schreiben, wo
genau dieses eigentlich ein typischer Fall für Assembler ist? Nur dazu,
daß man damit kaschieren kann, gar keine Ahnung von ARM-Assembler zu
haben? Dabei braucht man für den Startup gar keine wirklich guten
Assemblerkenntnisse, ein bissel Basiswissen reicht aus.
W.S.
W.S. schrieb:> 1. Die Tafel darf nicht irgendwo hin gelinkt werden, sondern hat ganz> präzise auf einer bestimmten Adresse zu stehen. Das ist eigentlich> ausdrücklich eine Assembler-Angelegenheit
Und wo steht die ganz bestimmte Adresse im C-Quelltext vom TO???
Wenn HW+SW Design zusammenpassen braucht man keine Assembler
Verrenkungen. ARM7TDMI war mal modern, aber das ist lange her und es
gibt mittlerweile besseres. Nur weil man das mal für die Lernbetty
brauchte muss die Entwicklung da nicht stehenbleiben. NXP hat die gcc
Vorlage nicht genutzt und den Startupcode in C geschrieben und das
funktioniert auch.
Johannes S. schrieb:> W.S. schrieb:>> 1. Die Tafel darf nicht irgendwo hin gelinkt werden, sondern hat ganz>> präzise auf einer bestimmten Adresse zu stehen. Das ist eigentlich>> ausdrücklich eine Assembler-Angelegenheit>> Und wo steht die ganz bestimmte Adresse im C-Quelltext vom TO???
Die steht normalerweise im Linkerskript. Und die Vektortabelle wird per
Attribut in eine spezielle Sektion geschoben.
W.S. schrieb:> 1. Die Tafel darf nicht irgendwo hin gelinkt werden, sondern hat ganz> präzise auf einer bestimmten Adresse zu stehen. Das ist eigentlich> ausdrücklich eine Assembler-Angelegenheit, denn alle höheren> Programmiersprachen sind ja genau dazu angelegt, ihren Benutzer eben> nicht mit derartigen Basics zu belästigen.
Eigentlich ist es die Angelegenheit des Linkers. Im Linkerskript muss
die Adresse angegeben werden.
> 2. Die Tafel muß ja auch mit Einträgen gefüllt werden, die man nicht> generell voraussehen kann. Deshalb muß jeder Eintrag mit einem> Default-Handler versehen werden, der aber dann, wenn man im Projekt> einen echten Handler hat, durch selbigen ersetzt werden muß. Daher das> Konstrukt mit dem "weak"-Attribut, das dann der Linker berücksichtigt.> Aber auch dieses ist so eigentlich nicht in C vorgesehen.
Und in Assembler ist das vorgesehen?
W.S. schrieb:> Und warum sollte man partout mit Krampf einen Startup in C schreiben, wo> genau dieses eigentlich ein typischer Fall für Assembler ist? Nur dazu,> daß man damit kaschieren kann, gar keine Ahnung von ARM-Assembler zu> haben? Dabei braucht man für den Startup gar keine wirklich guten> Assemblerkenntnisse, ein bissel Basiswissen reicht aus.
Oha da spricht jemand mit Erfahrung... nicht.
Hier ein Beispiel:
1
externunsignedint_DATA_ROM_START;
2
externunsignedint_DATA_RAM_START;
3
externunsignedint_DATA_RAM_END;
4
externunsignedint_BSS_START;
5
externunsignedint_BSS_END;
6
7
#define STACK_TOP 0x20005000
8
voidstartup();
9
10
unsignedint*myvectors[2]
11
__attribute__((section("vectors")))={
12
(unsignedint*)STACK_TOP,// stack pointer
13
(unsignedint*)startup// code entry point
14
};
15
16
voidmain();
17
18
voidstartup()
19
{
20
/* Copy data belonging to the `.data` section from its
21
* load time position on flash (ROM) to its run time position
22
* in SRAM.
23
*/
24
unsignedint*data_rom_start_p=&_DATA_ROM_START;
25
unsignedint*data_ram_start_p=&_DATA_RAM_START;
26
unsignedint*data_ram_end_p=&_DATA_RAM_END;
27
28
while(data_ram_start_p!=data_ram_end_p)
29
{
30
*data_ram_start_p=*data_rom_start_p;
31
data_ram_start_p++;
32
data_rom_start_p++;
33
}
34
35
/* Initialize data in the `.bss` section to zeros.
36
*/
37
unsignedint*bss_start_p=&_BSS_START;
38
unsignedint*bss_end_p=&_BSS_END;
39
40
while(bss_start_p!=bss_end_p)
41
{
42
*bss_start_p=0;
43
bss_start_p++;
44
}
45
46
47
/* Call the `main()` function defined in `test_program.c`.
Orakel schrieb:> Müssen wir dieses Gesülze von dir jetzt eigentlich jedes Mal lesen?
Das habe ich in meinem ganzen Leben zum ersten mal geschrieben.
> Besorg dir endlich mal ordentliche Lektüre zu C und zu C++ und lies es!
Du kennst mich nicht. Ich habe zwei Bücher von Bjarne gelesen, eins von
Kernighan und Ritchie, eins von Ulrich Breymann und eins an dessen Autor
Titel ich mich nicht mehr erinnere.
Also mach mal halblang!
Al3ko -. schrieb:> Deine Internetseite ist zur Zeit nicht verfügbar?
Die Seite ist zur Zeit verfügbar.
> Wo kann ich Band 2 finden?
Die Datei befindet sich auf der gleichen Seite. Ihr Dateiname endet mit
2.pdf (anstelle von 1.pdf).
http://stefanfrings.de/mikrocontroller_buch/index.html
Dinge wie dieses "weak" sind eben plattformspezifisch und Assembler ist
ebenso plattformspezifisch. Paßt. Sowas in C unterzubringen, ist
eigentlich entgegen dem Sinn von C als einer plattformübergreifenden
höheren Programmiersprache.
W.S.
W.S. schrieb:> Dinge wie dieses "weak" sind eben plattformspezifisch
Du hast schonwieder keine Ahnung!
Jetzt mal ne ganz ehrliche Frage: Was kannst du eigentlich?
Rolf M. schrieb:> Eigentlich ist es die Angelegenheit des Linkers. Im Linkerskript muss> die Adresse angegeben werden.
Ähem, nochwas:
1
PRESERVE8
2
THUMB
3
4
5
;VectorTableMappedtoAddress0atReset
6
7
AREARESET,CODE,READONLY
8
EXPORT__Vectors
9
10
__VectorsDCD__initial_sp;TopofStack
11
DCDHard_Reset;ResetHandler
12
...etc.
Damit ist das im Quellfile angegeben.
Es gibt bei einigen Chips noch ganz andere Dinge, die da ebenfalls auf
bestimmte Adressen festgenagelt werden müssen:
z.B. beim Kinetis MK22FN...
1
;
2
AREA|.ARM.__at_0x400|,CODE,READONLY
3
EXPORTFSEC
4
EXPORTFOPT
5
BackDoorK0DCB0xFF
6
BackDoorK1DCB0xFF
7
BackDoorK2DCB0xFF
8
BackDoorK3DCB0xFF
9
BackDoorK4DCB0xFF
10
BackDoorK5DCB0xFF
11
BackDoorK6DCB0xFF
12
BackDoorK7DCB0xFF
13
14
FPROT0DCB0xFF
15
FPROT1DCB0xFF
16
FPROT2DCB0xFF
17
FPROT3DCB0xFF
18
DCB0xFF
19
DCB0xFF
20
FSECDCB0xFE
21
FOPTDCB0xFF
22
23
ALIGN
24
END
Das ist die Protect-Sache. Wenn an dieser Stelle bunte Knete steht, dann
hat das ggf. putzige Nachwirkungen.
Oder was Ähnliches beim LPC11E12/14:
1
;
2
AREA|.ARM.__at_0x2FC|,CODE,READONLY
3
EXPORTCRP_Key
4
5
CRP_KeyDCD0xFFFFFFFF
6
7
ALIGN
8
END
Wie du siehst, gibt es in der Welt so einiges mehr als nur den
Startupcode.
W.S.