Hallo zusammen, ich versuche gerade meinen TCP IP Stack auf einem
ATMega32 direkt vor den Bootloader Bereich zu setzen.
Wenn ich dies z.b. mit dem Modul tcp.c/h mache indem ich in tcp.h
#define NET_SECTION _attribute_ ((section (".tcpipStack")))
schreibe und nach jeder Funktion "NET_SECTION" schreibe also:
void tcp_init(void)NET_SECTION;
als Linkerflag gebe ich folgendes mit:
-Wl,-section-start=.tcpipStack=0x4F00
... dann funktioniert das wunderbar.
Nun dachet ich mir, dass ich das define einfach in eine globale header
Datei schreiben kann und dann auch z.b. das Modul udp.c/h an diese
Section packe indem ich auch hier wieder in der udp.h hinter alle
Funktionen das "NET_SECTION" setze.
Dies geht leider nicht, da dann folgender Linkerfehler kommt:
c:/programme/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/bi
n/ld.exe: section .tcpipStack.1 [000088ee -> 00008917] overlaps section
.data [000088ee -> 00008901]
Woran kann das liegen? Überlappen dürfte eigentlich nichts, da noch genu
platz bleibt bis der eigentliche Bootloadercode anfängt.
Ich könnte mir vorstellen dass für das Modul tcp und udp jeweils
versucht wird an die selbe Stelle (4F00) den Code jeweiligen Code zu
setzen?!?
Funktioniren würde es natürlich wenn ich alles in einen .c/.h schreiben
würde, jedoch ist das auch nicht das ziel.
Würde mich über einen Tip freuen!
Mfg
Tobi
hm.. also irgendwie bekomme ich es nicht hin...
egal wie ich es drehe kommt ein Linkerfehler.
Ich muss doch irgendwie alle beliebigen Module ans Ende des RWW Teils
bekommen.
Also vor den Bootloader?!?
Ich könnte auch mehrere Sektions erstellen - also für jedes Modul eins.
Jedoch wenn ich dann in einem Modul was ändere muss ich wieder alle
manuell richtig platzieren damit keine Überschneidungen auftreten....
Das muss doch auch einfacher gehen.. Ich finde leider nichts dazu.
Würde mich über eine Hilfe freuen.
Mfg
Tobi
1) Mal im Mapfile nachgesehen, ob es Überlappung gibt?
Also keine Extrasection anlegen und dann mal schauen,
wie groß TCP und UDP wird. Dann kannst du ausrechnen,
ob es paßt.
2) Startaddresse der Section mal nach unten verschieben, ob es
dann klappt? Das wäre allerdings stochern und du fliegst
wahrscheinlich irgendwann nach einer Codeänderung wieder
auf die Klappe.
3) Wenn du nur TCP in die Section packst, dann geht es?
Wenn du nur UDP in die Section packst, dann geht es?
Wenn beide Teile drin sind, geht es nicht? Dann sind beide
Teile scheinbar zu groß.
Das entscheidende kleine Detail in der Fehlermeldung ist das ".1".
Sections gleichen Namens aus unterschiedlichen Modulen werden nicht
automatisch zusammengeführt. Statt dessen bekommen sie einen
Nummern-Suffix, um sie getrennt zu halten. Für .tcpipStack.1 hast du
aber keine Startadresse vorgegeben, also landet es hinter .text und
überlappt sich dann dort mit .data. Ich wüsste nicht, dass man das
irgendwie direkt über die Kommandozeile handhaben könnte. Ich sehe zwei
Möglichkeiten für dich:
1) Eigenes Linker-Script verwenden.
2) Eine ansonsten nicht benutzte Section verwenden, für die es schon im
Default-Script eine entsprechende Zusammenlegung gibt. .bootloader würde
sich z.B. anbieten.
Für mich ist die eigentliche Frage aber:
> Hallo zusammen, ich versuche gerade meinen TCP IP Stack auf einem> ATMega32 direkt vor den Bootloader Bereich zu setzen.
Warum willst du das überhaupt machen?
Hallo und danke für eure Antworten,
@900ss: Es ist schon so wie Stefan schrieb, dass ich geren möchte, das
die Teile automatisch zusammengeführt werden, wenn ich eigene Sections
anlege und eine Adresse zuweise klappt das schon. Nur sind es noch mehr
Module als nur die beiden und ich möchte das das automatisch irgendwie
funtkioniert.
@Stefan:
Stefan Ernst schrieb:> Für .tcpipStack.1 hast du> aber keine Startadresse vorgegeben, also landet es hinter .text und> überlappt sich dann dort mit .data.
Ok das klingt sinnig. Scheinbar ist das passiert. Ich hatte gehofft, man
kann eine Section vielleicht modulübergreifend per define irgendwie
deklarieren und so mehrere Module in eine Section packen.. schade.
Das mit dem Linkerscript habe ich auch schon irgendwo gelesen in
ähnlichem Zusammenhang. Leider hab ich da gar keine Ahnung wo ich da
ansetzen muss. Gibt es dafür auch ein Tut so wie man hier sehr gute Tuts
für alles mögliche andere findet? Oder hast du mir da ein paar kurze
Tips um mir dahingehend Starthilfe zu geben? )
Warum das ganze? Weil ich den TCP/IP Stack im Bootloader UND in der
Anwendung benötige und somit das gerne zentral ablegen würde. Da bietet
sich der Bereich vro dem Bootloader sehr gut an.
Bootloader wird dann zusammen mit dem Stack geflashed und die Anwendung
dann über den Bootloader über LAN.
Ich denke das mit dem Linkerscript wird die Lösung sein.
Vielen Dank für eure Hilfe bisher! :)
Tobi
Tobi schrieb:> Das mit dem Linkerscript habe ich auch schon irgendwo gelesen in> ähnlichem Zusammenhang. Leider hab ich da gar keine Ahnung wo ich da> ansetzen muss.
Warum dann nicht Möglichkeit 2?
Tobi schrieb:> Warum das ganze? Weil ich den TCP/IP Stack im Bootloader UND in der> Anwendung benötige und somit das gerne zentral ablegen würde.
Dir ist aber schon klar, dass dann noch ganz andere Probleme auf dich zu
kommen? Ist dir z.B. klar, dass der TCP/IP Stack dann keine globalen
(bzw. static) Daten direkt verwenden darf? Ansonsten müsstest du diesen
Daten auch noch einen festen Bereich im RAM zuweisen und der Anwendung
klar machen, dass dieser Bereich für sie tabu ist.
also Möglichkeit 2 verstehe ich nicht ganz. Wieso die Bootloadersection
nutzen? Dann wäre ich doch im Adressbereich des Bootloaders?!? Ich
möchte die Daten doch im RWW Bereich nicht NRWW.
Wegen den Bedenken des gemeinsamen Nutzen des TCP/IP Stacks.. ich
initialisiere den Stack sowohl im Bootloader als auch inder Anwendung
jeweils für sich neu.
MfG
Tobi
Tobi schrieb:> also Möglichkeit 2 verstehe ich nicht ganz. Wieso die Bootloadersection> nutzen? Dann wäre ich doch im Adressbereich des Bootloaders?!? Ich> möchte die Daten doch im RWW Bereich nicht NRWW.
"bootloader" ist doch bloß ein Name, der den eigentlich zugedachten
Adressbereich verdeutlichen soll. In Wirklichkeit kannst du die Section
an jede beliebige Adresse legen.
Tobi schrieb:> Wegen den Bedenken des gemeinsamen Nutzen des TCP/IP Stacks.. ich> initialisiere den Stack sowohl im Bootloader als auch inder Anwendung> jeweils für sich neu.
Vom Initialisieren der Daten habe ich nicht geredet, sondern von den
Adressen der globalen und statischen Daten. Bei direkten Zugriffen
kannst du in Applikation und Bootloader diese nicht neu vergeben.
und wie kann ich der section "bootloader" mehrere Module zuweisen?
...
du meinst also wenn ich den Stack im Bootloader initialisiere, was
bereits funktioniert, dann kann ich vom anwenderbereich später den Stack
nicht mehr verwenden? Ich muss michda nochmal schlau machen
Tobi schrieb:> und wie kann ich der section "bootloader" mehrere Module zuweisen?
So, wie du es mit deiner eigenen Section versucht hast. Wie gesagt, das
Zusammenführen für .bootloader müsste im Default-Script enthalten sein.
Tobi schrieb:> du meinst also wenn ich den Stack im Bootloader initialisiere, was> bereits funktioniert, dann kann ich vom anwenderbereich später den Stack> nicht mehr verwenden?
Wieso redest du schon wieder vom Initialisieren? Ich rede von Adressen
und Zugriffen auf diese im Allgemeinen. Machen wir ein konkretes
Beispiel. Eine Funktion soll sich von Aufruf zu Aufruf etwas merken,
sagen wir einfach irgendeinen Status (ein unit8_t reicht). Wie stellst
du dir vor, soll das bei dir aussehen?
blöd gefragt, wo finde ich das default script? Ich finde leider zum
linker script nirgends etwas und habe da auch noch nie etwas ändern
müssen.
...
Ich habe z.b. ein Modul "timer". Diesen benötige ich für den Timout beim
TCP. Hier muss ich mir dann z.b. den Timerwert merken. Dieser stckt in
einer Strukturvariablen. Die Instanz der Struktur ist global definiert.
Das ist wohl worauf du hinaus willst. Ich hätte nun angenommen, das ich
sowohl vom Bootloader (bereits erfolgreich getestet) eine solche Instanz
erzeugen kann als auch vom Anwenderbereich und diese der globalen
Variablen zuweisen?!?
Diese Instanz wird allerdings nicht von beiden Bereichen gleichzeitig
verwendet bzw. soll nicht über diese hinaus von bestand bleiben.
Danke für deine Geduld! :)
Tobi schrieb:> blöd gefragt, wo finde ich das default script?
Ok, dann frage ich mal blöd zurück: wozu willst du das wissen? Es ist
doch gerade der Vorteil von Variante 2, dass du mit Linker-Skripten
nichts zu tun hast. Das Default-Skript ist das, was passend zum
gewählten AVR-Typ automatisch verwendet wird.
Tobi schrieb:> Die Instanz der Struktur ist global definiert.> Das ist wohl worauf du hinaus willst. Ich hätte nun angenommen, das ich> sowohl vom Bootloader (bereits erfolgreich getestet) eine solche Instanz> erzeugen kann als auch vom Anwenderbereich und diese der globalen> Variablen zuweisen?!?
Zeige die Deklaration/Definition dieser globalen Variable und den
Zugriff darauf in der Funktion (konkreten Code, keine Beschreibung).
Stefan Ernst schrieb:> Ok, dann frage ich mal blöd zurück: wozu willst du das wissen? Es ist> doch gerade der Vorteil von Variante 2, dass du mit Linker-Skripten> nichts zu tun hast. Das Default-Skript ist das, was passend zum> gewählten AVR-Typ automatisch verwendet wird.
hm... ich verstehe nun immernoch nicht wie ich dann mehrere Module da
reinbekommen soll...
Stefan Ernst schrieb:> Zeige die Deklaration/Definition dieser globalen Variable und den> Zugriff darauf in der Funktion (konkreten Code, keine Beschreibung).
ok als beispiel die globale instanz eines tcp_sockets
1
tcp_Sockettcp_Sockettable[MAX_TCP_CONNECTIONS];
dann Ausschnitt der Funtion zum Senden eines TCP Packets. Es wird ein
TCP Packet mit den richtigen Daten gefüllt, gesendet und ein Timer
gestartet welcher sich in der TCP Struktur befindet.
Tobi schrieb:> hm... ich verstehe nun immernoch nicht wie ich dann mehrere Module da> reinbekommen soll...
Liest du nicht, was ich schreibe? Was ist an "So, wie du es mit deiner
eigenen Section versucht hast." unklar? Du hast bereits einen Versuch
mit ".tcpipStack" unternommen. Jetzt machst du das gleiche mit
".bootloader".
Tobi schrieb:> ok als beispiel ...
Und genau das geht so in die Hose. Wenn du jetzt in der Applikation die
gleiche globale Variable anlegst, hat die dort eine andere Adresse. Die
Funktion greift aber direkt zu, was bedeutet, dass die Adresse fest im
Binär-Code verankert ist. Wenn die Funktion also aus der Applikation
heraus aufgerufen wird, greift die Funktion trotzdem auf die Adressen
zu, die die Variable im Bootloader hat, in der Applikation stehen an
diesen Adressen aber ganz andere Dinge.
Unabhängig von globalen Variablen: ich halte das Konzept so für
tödlich. Wenn der Bootloader Dinge benutzen will, sollten sie sich
auch in seinem Bereich befinden, alles andere ist riskant (weil der
Bootloader es ggf. selbst überschreiben könnte, und weil die CPU
angehalten wird, wenn der NRWW-Bereich geschrieben wird).
Wenn du das Zeug, das im Bootloader steht, dann außerdem noch aus
der Applikation benutzen willst, dann platzierst du dir am einfachsten
an den Anfang des Bootloaders eine Vektortabelle, die auf die
eigentlichen Einsprungpunkte im Loader verzweigt. Aus Sicht der
Applikation wird dann immer die gleiche Adresse aufgerufen für eine
bestimmte Funktion (genauso wie weiland im CP/M-BIOS), und wo diese
genau dann implementiert ist, interessiert kein Schwein mehr.
Bei dieser Vorgehensweise kannst du Bootloader (mit dem IP-Stack)
und eigentliche Applikation völlig separat entwickeln und linken,
was für einen Bootloader eigentlich auch nur so Sinn hat, denn am Ende
müssen beide voneinander (bis auf den Einsprungvektor) logisch
unabhängig sein.
Jörg Wunsch schrieb:> Wenn du das Zeug, das im Bootloader steht, dann außerdem noch aus> der Applikation benutzen willst, dann platzierst du dir am einfachsten> an den Anfang des Bootloaders eine Vektortabelle, die auf die> eigentlichen Einsprungpunkte im Loader verzweigt. Aus Sicht der> Applikation wird dann immer die gleiche Adresse aufgerufen für eine> bestimmte Funktion (genauso wie weiland im CP/M-BIOS), und wo diese> genau dann implementiert ist, interessiert kein Schwein mehr.>> Bei dieser Vorgehensweise kannst du Bootloader (mit dem IP-Stack)> und eigentliche Applikation völlig separat entwickeln und linken,> was für einen Bootloader eigentlich auch nur so Sinn hat, denn am Ende> müssen beide voneinander (bis auf den Einsprungvektor) logisch> unabhängig sein.
Nur so als Hinweis an Tobi:
Das löst aber nicht die von mir angesprochene
Problematik, sondern behandelt einen anderen Aspekt dieses “Recyclings“.
Das Grundproblem das ich habe ist dass der ganze Tcp Stack nicht in den
Bootloader reinpasst. Sonst haette ich ihn sowieso zweimal
implementiert. Einmal fuer den Bootloader abgespeckt und einmal komplett
fuer die anwendung.
Ich komme leider nicht unter 6500Bytes in der abgespeckten Version.
Daher kommt die Idee es nun in den Anwenderbereich zu packen und es dann
gleich fuer beide Bereiche zu nutzen.
Ansonsten muesste ich den naechst groesseren chip nehmen... Wollte aber
gerne den mega32 behalten.
Oder ich implementiere nur udp im Bootloader und mach ne eigene kleine
Flussteuerung. Wird einfach da ich eh die Pakete sequenziell erwarte und
vorher nicht weiter mache.
Wie waere die Idee den Tcp Stack einmal normal und einmal abgespecktim
anwenderbereich zu implementieren und den abgespeckten nurim Bootloader
zu nutzen? Kommt ja eigentlich vom platzbedarf auf meine urspruengliche
Idee aufs gleiche raus?!?
Sorry Stefan. .. Klar verstehe ich das mit der bootloadersection...
Alsogeht das dass ich in beliebigen Modulen an beliebigen Funktionen
diese Section deklariere? Muss ich heute abend mal testen.
Das mit den globalen variablen war mir so noch nicht bewusst... Danke
fuer den Hinweis.
Joerg danke fuer den Tip mit der Vektortabelle... Ich muss mal
ueberlegen in wieweit mir das hilfreich sein koennte.
Danke fuer eure Hilfe!
Tobi schrieb:> Das mit den globalen variablen war mir so noch nicht bewusst... Danke> fuer den Hinweis.
Nur so nebenbei, das gleiche gilt natürlich auch für
Static-Local-Variablen.
hm.. Also das mit der .bootloader Section funktioniert so scheinbar
nicht.
Folgendes in einer config.h definiert:
#define NET_SECTION _attribute_ ((section (".bootloader")))
und das in der tcp.h:
void tcp_init(void)NET_SECTION;
und in udp.h:
void udp_init(void)NET_SECTION;
im linker dann die Adresse für .bootloader auf 0x0200
funktioniert leider nicht. wen ich die deklaration z.b. in udp.h
weglasse funktioniert es. So wie mit meiner .tcpipStack Section...
Also was mache ich falsch?
Tobi schrieb:> funktioniert leider nicht. wen ich die deklaration z.b. in udp.h> weglasse funktioniert es. So wie mit meiner .tcpipStack Section...
Ich habe mal in die Default-Linker-Skripte geschaut, und die von mir
vermutete Zusammenführung der .bootloader.* Sections gibt es dort
tatsächlich nicht.
Sorry, dass ich dich diesbezüglich in die Irre geführt habe.
Hallo,
ich habe auf der Startseite gerade diesen Thread entdeckt und ich muss
gestehen, dass ich ihn nicht komplett durchgelesen habe.
Ich habe aber vor kurzem den LwIP-Stack auf einem Cortex M3
implementiert und den Stack in den oberen Flashbereich gelinkt. Die
Adressen der Funktionen des Stacks kommen in ein Array, welches man an
eine absolute Adresse linkt. Wie schon oben beschrieben kann man sowohl
den Stack als auch die eigentliche Anwendung unabhängig voneinander
entwickeln ohne das irgendwas später nicht mehr funktioniert. Ich
brauchte nur ein ganz einfaches Linkerscript zu schreiben, welches dies
erledigt. Und ich hatte vorher keine Ahnung von Linkerscripts. Dann
schreibt man nur noch ein Modul welches die Arrayadresse und damit die
Funktionsadressen wieder auflöst. Die Anwendung sieht von dem Stack
eigentlich nichts. Und das JTAG-Interface auch nicht, was die
Codegrößenbegrenzung aushebelt. Das war eigentlich auch der Sinn warum
ich es gemacht habe.
Nur mal nebenbei. Die NXP LPC-134X Serie enthält ab Werk im oberen
Flashbereich (nur Lesezugriff) USB Treiber für HID und Mass-Storage. Der
Zugriff erfolgt hier ebenfalls über absolute Adressen.
gurgel doch mal wie man mit hilfe einer jump-table code von zwei
applikationen gemeinsam nutzen kann.
den residenten code (in deinem fall der tcp/ip stack) sinnvoll in eine
eigene section mit bekannter startadresse lokieren. dazu musst du ggf.
das default linker script modifizieren.
gruss, tom.
also haltet mich für blöd, aber wo fidne ich denn das linker script das
AVR Studio verwendet... es müsste doch eine *.x Endung haben... Ich
finde aber nichts dazu.
Gibt es denn irgendwo hier ein gutes Tut wie man das Script zu verstehen
hat und was man da für Möglichkeiten hat?
Tobi schrieb:> also haltet mich für blöd, aber wo fidne ich denn das linker script das> AVR Studio verwendet... es müsste doch eine *.x Endung haben... Ich> finde aber nichts dazu.
Bei mir ist es unter /usr/local/avr/lib/ldscripts, aber du kannst
daran zumindest erkennen, dass ich kein AVR Studio benutze. ;-)
> Gibt es denn irgendwo hier ein gutes Tut wie man das Script zu verstehen> hat und was man da für Möglichkeiten hat?
Ein was? Ein Tut? Klingt wie'n Auto auf dem Kinderkarussel ... :)
Der Linker ist Bestandteil der GNU binutils und dort dokumentiert.
Da sollte es auch eine Beschreibung der Linkerscripts geben. Nein,
ein "Tut" wird dafür noch niemand geschrieben haben. Die, die sowas
anfassen, sollten normalerweise mit der Doku zurecht kommen.
Jörg Wunsch schrieb:> Ein was? Ein Tut? Klingt wie'n Auto auf dem Kinderkarussel ... :)
loooool
Jörg Wunsch schrieb:> ein,> ein "Tut" wird dafür noch niemand geschrieben haben. Die, die sowas> anfassen, sollten normalerweise mit der Doku zurecht kommen.
Ok. Naja das könnte man beim Bootloader auch sagen und trotzdem gibts
hier super Tutorials (Extra für dich ausgeschrieben :) dazu.
Also wenn das klappt mit dem Linkerscript, dann wären zumindest mal die
Probleme mit den Sections gelöst.
Das zweite Problem mit den globalen und statischen Variablen werde ich
wohl mit einer zusätzlichen Header lösen in der ich die Variablen auch
fest an eine Adresse linke (geht ja glaub ich genauso mit "attribute
section") und diese Header dann sowohl beim Bootloader als auch in der
Anwendung linke.
Dann muss ich noch sicherstellen das der Bootloader nur von 0x0000 bis
Beginn des TCP/IP Stacks flashed und das wars dann.
Falls jemand noch nen Tip zu alldem hat.. immer her damit.
Ich melde mich dann mit dem Erfahrungsbericht :)
Tobi
Hallo nochmals zusammen,
also ich hab es jetzt hinbekommen dass alle Module einer Section
zugeordnet werden können und zwar so:
Im avr5.x ( Linker file) direkt vor der text Section. ( diese ist an
Adresse 0x7000 = Bootloadebereich verschoben)
1
.tcpipStack0x7000-0x2238:{*(.tcpipStack)}
2
.text:
3
{
im Code hinter jede Funktion egal in welchem Modul folgendes:
1
__attribute__((section(".tcpipStack")))
das wars dann schon.
Nur leider kann ich zum Zeitpunkt an dem ich im Linker Script oben
meiner Section die Adresse zuweise weder die Adresse des Bootloaders
angeben werde die size meiner Section um GENAU vor den Bootloaderbereich
zu kommen.
Desshalb ist das oben händisch implementiert.
Geht das nicht irgendwie? Hatte an sowas gehofft:
Leider funktioniert das so nicht da zu diesem Zeitpunkt leider weder die
Adresse von .text noch die Größe von meiner eigenen Section bekannt ist
?!?
Geht das nicht irgendwie automatisch noch?
Hallo nochmals,
also das mit der Section klappt ja soweit und alles was den TCP/IP Stack
betrifft liegt nun direkt unter der Bootloadersection.
Scheinbar ergibt sich aber nun noch ein weitere Problem..
Wenn ich nun vom Bootloader eine Funktion aus dem Stack aufrufe,
funktioniert das soweit. Die Funktion kehrt auch wieder korrekt zurück.
Wenn ich nun allerdings vom Bootloader in den Stack springe und von dort
dann wiederum eine Funktion im Bootloader aufrufe, dann kehrt diese
Funktion irgendwie nicht mehr korrekt in den Stack zurück.
Innerhalb des Stacks versuche ich an eine Funktion im Bootloader zu
springen (über gesicherten Funktionspointer). Dies funktioniert soweit.
Nur wenn ich dann zurückspringen möchte geht das wohl schief und
dasProgramm landet im nirgendwo... weitere Kommunikaionen über LAN sind
dann auch nicht mehr möglich. Der retrun scheint zwar irgendwo im Stack
wieder zu landen, jedoch an falscher Stelle.
Diese Funktion wird über den Funktionspointer noch erfolgreich aus dem
TCP/IP Stack aufgerufen:
1
uint8_tgetData(uint8_t*buf,uint16_tlen)
2
{
3
72d0:dc01movwr26,r24
4
uint8_tcmd=*buf++;
5
6
// if command is flash command
7
if(cmd==0x04){
8
72d2:8c91ldr24,X
9
72d4:8430cpir24,0x04;4
10
72d6:71f4brne.+28;0x72f4<getData+0x24>
11
return0;
12
}
13
14
uint8_tgetData(uint8_t*buf,uint16_tlen)
15
{
16
uint8_tcmd=*buf++;
17
72d8:fd01movwr30,r26
18
72da:3196adiwr30,0x01;1
19
20
// if command is flash command
21
if(cmd==0x04){
22
uint16_taddr=(*buf++)<<8;
23
72dc:1196adiwr26,0x01;1
24
72de:7c91ldr23,X
25
72e0:60e0ldir22,0x00;0
26
addr+=*buf++;
27
28
flashPage(addr,buf);
29
72e2:2181lddr18,Z+1;0x01
30
72e4:620faddr22,r18
31
72e6:711dadcr23,r1
32
72e8:80e0ldir24,0x00;0
33
72ea:90e0ldir25,0x00;0
34
72ec:3296adiwr30,0x02;2
35
72ee:af01movwr20,r30
36
72f0:0e942d39call0x725a;0x725a<flashPage>
37
//buf[0] = 0xab;
38
//TCP_SendPacket(SOCKET, 1, buf);
39
}
40
41
return0;
42
}
43
72f4:80e0ldir24,0x00;0
44
72f6:0895ret
Das Flashen der übergebenen Daten funktioniert, darum kann ich sicher
sein das die Funktion korrekt aufgerufen wird.
"TCP_SendPacket(SOCKET, 1, buf);" ist hier auskommentiert, würde nicht
funktionieren genau wie der return in den Stack. (Funktion liegt auch
wieder im TCP/IP Stack welcher unter dem Bootloader-Bereich liegt)
Hoffe es kommt noch jemand mit :)
Jemand eine Ahnung an was das liegen könnte?
Danke!
Tobi
hmmm..
also ich vermute es liegt am Aufruf der Funktion per Funktionspointer..
1
tcp_Sockettable[socket].fp(buf,dataLength);
2
5f1c:e0912302ldsr30,0x0223
3
5f20:f0912402ldsr31,0x0224
4
5f24:ce01movwr24,r28
5
5f26:0296adiwr24,0x02;2
6
5f28:b501movwr22,r10
7
5f2a:0995icall
zwar funktioniert dieser Aufruf in den Bootloaderbereich jedoch komme
ich hierher scheinbar nicht mehr zurück.. liegt dies an dem icall?
(Mit dem Codeausschnitt wird der obere Code im Beitrag zuvor aufgerufen)
Tobi schrieb:> also ich vermute es liegt am Aufruf der Funktion per Funktionspointer..
Ich vermute eher der Fehler liegt in flashPage.
Vielleicht RWW-Section nicht wieder enabled?
ok.. blöder Fehler von mir.. hab eine Array von 100 Byte Größe
deklariert gehabt und 128 Byte reingeschrieben... kann schlecht gehen..
kam nur nicht gleich drauf weil nicht irgendein Mist passiert ist
sondern trotzdem eine andere Funktion ausgeführt wurde... Zufall..
Ok das funktioniert nun soweit.. nun komme ich zu dem Problem mit den
globalen Vaiablen... ich finde dazu leider nicht viel.
Irgend ein Ansatz mit Sections... aber ist das das richtige?
Könnte jemand bitte ein kleines Beispiel posten wie man das zu
realisieren hat?
Wie setze ich eine Variable an eine feste Adresse im Ram die dann auch
noch der Anwendung später nach dem Switch in die Applikation bekannt
ist?!?
Danke!
Tobi
hallo zusammen,
also habe es nun mit sections folgendermaßen für eine Beispiel - Globale
Variable versucht:
im main.c file:
1
intxx__attribute__((section(".myGlobals")));
als Linkeroption:
1
-Wl,--section-start=.version=0x800460
und dies bei beiden Projekten.. also im Bootloaderprojekt als auch im
Anwenderprojekt.
Leider kommt beim Flashversuch des Bootloaders "0x00800460 is out of
range"
Nur wie bestimme ich für beide Projekte eine möglichst praktische Stelle
an die ich mehrere globale Variablen fest addressieren kann?
Die Section Übersicht in den *.lss files sehen folgendermaßen aus:
im Bootloader Projekt:
Tobi schrieb:> Leider kommt beim Flashversuch des Bootloaders "0x00800460 is out of> range"
Dann musst du dein Makefile modifizieren, um die Section aus dem
HEX-File rauszuhalten (hat darin ja auch nichts verloren).
Tobi schrieb:> Nur wie bestimme ich für beide Projekte eine möglichst praktische Stelle> an die ich mehrere globale Variablen fest addressieren kann?
Ich würde ja das ganze Geraffel vermeiden, und den Code entsprechend
modifizieren, dass es keine direkten Zugriffe auf globale Daten gibt
(sondern nur indirekte).
Hy Stefan.
danke fuer deine antwort.
Wie muss ich denn das makefile modifizieren. und wie meinst du indirekte
zugriffe? alle in einen struct und dann nur einen pointer drauf?
mir ist nicht ganz klar wie das dann aussehen koennte.
bin fuer verbesserungsvorschlaege offen :)
Tobi schrieb:> Wie muss ich denn das makefile modifizieren.
An passender Stelle ein "-R .myGlobals" einfügen.
Tobi schrieb:> und wie meinst du indirekte> zugriffe? alle in einen struct und dann nur einen pointer drauf?
Ja, wäre eine Möglichkeit.
Tobi schrieb:> mir ist nicht ganz klar wie das dann aussehen koennte.
Zum Beispiel deine Funktion TCP_SendPacket oben.
Statt direkt
Tobi schrieb:> Wie setze ich eine Variable an eine feste Adresse im Ram die dann auch> noch der Anwendung später nach dem Switch in die Applikation bekannt> ist?!?
Das einfachste ist sicherlich, den Stack Pointer am Anfang des
Programmes nicht auf die höchste Adresse zu setzen, sondern entsprechend
niedriger. So schaffst Du einen sicheren Platz, in dem Du Deine globalen
Daten speichern kannst.
super.. endlich hab ich es hinbekommen...
im Makefile muss man wie Stefan schrieb noch etwas ändern:
Die passende Stelle für "-R .myGlobals" ist bei den HEX_FLASH_FLAGS.
Nun funktioniert es.. danke euch!!
Tobi
Achso.. leider muss ich dazu vorher das Makefile exportieren und diese
Änderung machen. Danach muss man dieses externe Makefile verwenden.
Gibt es keine Möglichkeit dies direkt im AVRStudio einzugeben?!?
Finde nichts dazu.
Falls du Datensections verwendest:
Alle Variablen in .myGlobals zu machen ist keine gute Idee.
1) Du brauchst immer das gleiche Layout innerhalb der Section falls mehr
als ein Objekt drinne ist. D.h. du willst eine Section für jedes
globale Objekt.
2) Wenn du eine Section so nennst, kann es dir passieren, daß der
Compiler keinen Startupcode zum Initialisieren der Section erzeugt :-)