Arduino Mega2560 mit externem RAM: linker flag für .data section geht nicht

#6924293
Lesenswert?

Hallo,

ich habe einem Arduino Mega2560 32k externes RAM gegönnt und versuche 
das jetzt möglichst flexibel einzurichten.
Die Methode die auf 
https://hackaday.io/project/21561-arduino-mega-2560-32kb-ram-shield 
erwähnt wird, lässt ja nur zu dynamische Variablen in den XRAM zu 
schieben.

Laut https://www.nongnu.org/avr-libc/user-manual/malloc.html kann man 
auch .data und .bss in den externen Speicher schieben, aber das 
funktioniert nicht :/

Ich habe mir in der Arduino-Umgebung ein eigenes board erstellt.
Dazu reicht es im sketch-folder einen Ordner mit einer boards.txt 
anzulegen.
Um die Linker flags übergeben zu können braucht es dann noch eine 
platforms.txt mit dem Eintrag
1
compiler.ldflags=-Wl,--section-start,.data=0x802200,--defsym=__heap_end=0x80A1FF

leider klappt das nicht - ich habe es nicht weiter untersucht, aber an 
der seriellen kommt keine Ausgabe

Wenn ich jedoch nur den heap in den externen RAM verweise
1
compiler.ldflags=-Wl,--defsym=__heap_start=0x802200,--defsym=__heap_end=0x80A1FF
dann funktionniert das wunderbar.
Allerdings habe ich dann wieder die Einschränkung dass nur dynamisch 
erstellte Variablen dahin verwiesen werden.

Leider ist mein Verständnis von Compiler und Linker recht gering und ich 
weiss nicht wie ich hier weitersuchen soll, bzw. was da überhaupt 
passiert.

Bin für jeden Hinweis dankbar!
Angehängte Dateien:
Gast #6924325
Lesenswert?

Bob A. schrieb:
> Die Methode die auf
> https://hackaday.io/project/21561-arduino-mega-2560-32kb-ram-shield
> erwähnt wird

Nachdem ich eine zeitlang bei den hackadays gesucht habe und
dort nichts gefunden habe erlaube ich mir dir die Frage zu stellen
ob du jemals den Begriff "Abblock-Kondensator" gehört hast.

Klar, ich weiss, das ist reine Esoterik, Abblock-Kondensatoren
sind rein für die Ästhetik und zeugen davon dass der geneigte
Arduino-Besitzer genug Geld hat um seine Werke zu verschönern.
Ansonsten machen die Kondensatoren ja keinen Sinn, ausser
Beschäftigungstherapie.

Aber ich frag halt mal ..... ich weiss, das macht dein Speicher-
Problem nicht besser ....
#6924336
Lesenswert?

Ich schrub doch: "bin für jeden Hinweis dankbar" :)

also Danke dafür!
Habe das im Eifer  und in der Freude dass der Drahtverhau tatsächlich 
funzt grad mal vergessen.
Wird nachgerüstet und kommt auch ganz sicher ins fertige Layout.
Und ja, leider hilfts bei der eigentlichen Fragestellung nicht weiter... 
auch wenns womöglich später die Suche nach dem Ursprung von obskurem, 
sporadischen Fehlverhalten unnötig macht :)

Ob der Abblock-C bei all den schönen Antennen aber das größte Problem 
ist...
Gast #6924379
Lesenswert?

Bob A. schrieb:
> Ob der Abblock-C bei all den schönen Antennen aber das größte Problem
> ist...

Nicht der_ sondern _die! Für jeden Baustein einen und für die
Board-zu-Board-Verbindung noch einen Elko 10-47uF.

Du fällst aus der Rolle der Arduino-Maker! Du meinst wirklich
man könnte Kondensatoren vorsichtshalber einbauen? Ich kenne
nur die Betonköpfe die sagen es geht auch ohne.

Selbst hackadays turnt dir vor dass es keine Abblock-
Kondensatoren braucht!
#6924673
Lesenswert?

ich hab mir jetzt mal das .elf angeschaut mit dem netten online viewer 
von Bastian Molkenthin 
(http://www.sunshine2k.de/coding/javascript/onlineelfviewer/onlineelfviewer.html)

Nur schade dass ich nicht so ganz kapiere was ich da sehe...
Mir scheint dass es in dem Bereich "Program Header Table" sich die 
Addressen für .data und .bss wiederfinden. Und zwar unterteilt in 
virtuelle und physische Addressen.

im XMEM: (Einträge eingekürzt damit es keinen Zeilenumbruch gibt)
1
Program header tables
2
=====================
3

4
Type                Offset              VAddr               PAddr               
5
PT_LOAD             0x00000094          0x00000000          0x00000000       
6
PT_LOAD             0x00000D94          0x00802200          0x00000D00        
7
PT_LOAD             0x00000E5E          0x008022CA          0x008022CA

Im section header sieht es dann so aus (auch gekürzt)
1
0                                  SHT_NULL       0x00000000
2
1              .data               SHT_PROGBITS   0x00802200
3
2              .text               SHT_PROGBITS   0x00000000
4
3              .bss                SHT_NOBITS     0x008022CA

Da oben die gleichen Addressen auftauchen und auch Offset und Size 
passen gehe ich davon aus dass es sich auch bei den obigen Einträgen um 
.data und .bss handelt.

im normalen Speicher (auch gekürzt)
1
Program header tables
2
=====================
3

4
Type                Offset              VAddr               PAddr          
5
PT_LOAD             0x00000094          0x00000000          0x00000000       
6
PT_LOAD             0x00000D94          0x00800200          0x00000D00         
7
PT_LOAD             0x00000E5E          0x008002CA          0x008002CA

Interessant finde ich, dass sich die Physiche Adresse von .data nicht 
ändert, die von .bss aber sehr wohl.
Ob das was zu bedeuten hat - dafür reicht mein Wissensstand nicht. 
Leider!

Weiterhin ist mir aufgefallen dass bei der XMEM-Variante für 
DATA_REGION_ORIGIN (doppelte underscores vorn und hinten entfernt um 
Formatierung zu verhindern) der Wert 0x0800200 erhalten bleibt, 
__data_start
 aber den Wert 0x0802200 zugewiesen bekommt.

Auch hier fehlt mir das nötige Wissen um das beurteilen zu können...

Würd mich freuen wenn jemand mich aufschlauen kann, bzw. mich in die 
richtige Richtung weist wo man sich selber aufschlauen kann...
Gast #6924940
Lesenswert?

Bob A. schrieb:
> leider klappt das nicht - ich habe es nicht weiter untersucht, aber an
> der seriellen kommt keine Ausgabe

Das Problem wird sein, dass in XMCRA das SRE Bit gesetzt sein muss 
bevor die Variablen (z.B. Serial) initialisiert werden.
Das kann man in einer frühen .init Section tun.
Gast #6925362
Lesenswert?

> Das kann man in einer frühen .init Section tun.

Das muss bereits im Startup-Code, der ja die Data-Sektion ins RAM 
kopiert, drin sein.

Aber mal ehrlich: was soll der Krampf, die vermurksten 2560er noch mit 
externem RAM zu erweitern - die werden dadurch nicht besser.  Mehr als 
64kB Kode+Daten wird mit 8-Bit-CPUs immer ein häßliches Gewurschtel - da 
sollte man doch mal den Schritt zu 32-Bit-CPUs wagen.  Ist ja nicht so, 
dass die schwieriger zu kommen oder teurer sind ...
Gast #6925645
Lesenswert?

Bob A. schrieb:
> Hallo EAF,
>
> auch wenn ich wenig Ahnung habe klingt das einleuchtend.
> nur - wie kann ich das bewerkstelligen?
> Hast du Doku zu den ganzen .init Sachen, evtl. Beispiele? Würde mich
> gerne einlesen, weiss aber nicht wo anfangen
1
void enableExternalMemory() __attribute__((naked,used)) __attribute__((section (".init1"))); 
2
void enableExternalMemory()
3
{
4
  XMCRA = (1<<SRE);
5
  //XMCRA |= (1<<SRE);
6
}
7

8
void setup() 
9
{
10
}
11

12
void loop() 
13
{
14
}

Die Doku der Gcc Toolchain ist hier wohl maßgeblich.
#6929671
Lesenswert?

Da ändert sich leider genau nix wenn ich das Beispiel mit .init1 
verwende

Addressen ohne .init1
1
08:27:29.020 -> Dynamic buffer 1 of 4096 bytes created, address: 0x11F9
2
08:27:29.020 -> Dynamic buffer 2 of 4096 bytes created, address: 0x1F9
3
08:27:29.068 -> Dynamic buffer 3 of 4096 bytes created, address: 0xF1F9
4
08:27:29.068 -> Dynamic buffer 4 of 4096 bytes created, address: 0xE1F9
5
08:27:29.068 -> Dynamic buffer 5 of 4096 bytes created, address: 0xD1F9
6
08:27:29.068 -> Dynamic buffer 6 of 4096 bytes created, address: 0x2376
7
08:27:29.068 -> Dynamic buffer 7 of 4096 bytes
buffer 6 und 7 werden dynamisch erzeugt und korrekt irgendwo hinter 
0x2200 und vor 0xA1FF geschoben

hier habe ich die Fkt. enableExternalMemory() wie oben beschrieben 
eingefügt
1
08:29:43.135 -> Dynamic buffer 1 of 4096 bytes created, address: 0x11F9
2
08:29:43.135 -> Dynamic buffer 2 of 4096 bytes created, address: 0x1F9
3
08:29:43.135 -> Dynamic buffer 3 of 4096 bytes created, address: 0xF1F9
4
08:29:43.135 -> Dynamic buffer 4 of 4096 bytes created, address: 0xE1F9
5
08:29:43.182 -> Dynamic buffer 5 of 4096 bytes created, address: 0xD1F9
6
08:29:43.182 -> Dynamic buffer 6 of 4096 bytes created, address: 0x2376
7
08:29:43.182 -> Dynamic buffer 7 of 4096 bytes

Alles wie gehabt :(

Wie kann ich den startup-code modifizieren, und das dann auch noch so 
dass es abhängig von der board-Auswahl in der Arduino IDE gemacht wird?
#6929695
Lesenswert?

Ich habe den Test von
https://hackaday.io/project/21561-arduino-mega-2560-32kb-ram-shield
laufen lassen
Sagt: alles in Ordnung selbst mit 0 waitstate
Hast du da eine bessere Möglichkeit das zu testen?

Ja ich weiss, die Addressen sind total wirr. Keine Ahnung wie das 
zustande kommt...
Eigentlich dürfte ja auch nix hinter 0xA1FF addressiert werden da das 
als heap_end gefiniert wurde.
Zumindest soweit ich das verstanden habe...
#6929719
Lesenswert?

EAF schrieb:
> Die Doku der Gcc Toolchain ist hier wohl maßgeblich.

Eigentlich die der avrlibc.

https://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_ext_ram

Bob A. schrieb:
> ich hab mir jetzt mal das .elf angeschaut mit dem netten online viewer
> von Bastian Molkenthin
> 
(http://www.sunshine2k.de/coding/javascript/onlineelfviewer/onlineelfviewer.html)
>
> Nur schade dass ich nicht so ganz kapiere was ich da sehe...

Ich sach mal, in Anbetracht der völlig wirren Adressen, die das tool 
ausspuckt, vergiß das halt einfach.

Oliver
Gast #6929723
Lesenswert?

foobar schrieb:
> Mehr als
> 64kB Kode+Daten wird mit 8-Bit-CPUs immer ein häßliches Gewurschtel - da
> sollte man doch mal den Schritt zu 32-Bit-CPUs wagen.  Ist ja nicht so,
> dass die schwieriger zu kommen oder teurer sind ...

Genau, Arduino Due hat 96 KM SRAM direkt im uC. Kann genau wie gewohnt 
mit der Arduino IDE programmiert werden. Warum sich mit den antiken 
8-Bit-Controllern und ihrer schmalen Ausstattung rumplagen, während 
längst wesentlich besser ausgestattete Controller Standard sind...
#6929726
Lesenswert?

Oliver S. schrieb:
> Ich sach mal, in Anbetracht der völlig wirren Adressen, die das tool
> ausspuckt, vergiß das halt einfach.

Wieso wirr?

die wirren Adressen kommen nicht vom Tool sondern von "meinem" 
Test-sketch
1
void setup()
2
{
3
  uint32_t arraysize = 1024;
4
  Serial.begin(9600);
5
  
6
  XMCRA |= 1ul<<7; // Switch ext mem iface on
7
  XMCRB = 0;
8

9
/*------------------------------------
10
  __malloc_heap_start = (char*)0x8000;
11
  __malloc_heap_end   = (char*)0xFFFF;
12
//-------------------------------------*/
13
//*
14
  uint32_t dataBuffer1[arraysize];
15
  uint32_t dataBuffer2[arraysize];
16
  uint32_t dataBuffer3[arraysize];
17
  uint32_t dataBuffer4[arraysize];
18
  uint32_t dataBuffer5[arraysize];
19
  uint32_t* dataBuffer6 = new uint32_t[arraysize];
20
  uint32_t* dataBuffer7 = new uint32_t[arraysize];
21
//------------------------------------------------*/  
22
/*
23
  uint32_t dataBuffer1[arraysize];
24
  uint32_t dataBuffer2[arraysize];
25
  uint32_t dataBuffer3[arraysize];
26
  uint32_t dataBuffer4[arraysize];
27
  uint32_t dataBuffer5[arraysize];
28
  uint32_t dataBuffer6[arraysize];
29
  uint32_t dataBuffer7[arraysize];
30
//--------------------------------*/
31
  
32
  Serial.println();
33
  Serial.print("Dynamic buffer 1 of ");
34
  Serial.print(arraysize * sizeof(uint32_t));
35
  Serial.print(" bytes created, address: 0x");
36
  Serial.println((uintptr_t)dataBuffer1, HEX);
37
  Serial.print("Dynamic buffer 2 of ");
38
  Serial.print(arraysize * sizeof(uint32_t));
39
  Serial.print(" bytes created, address: 0x");
40
  Serial.println((uintptr_t)dataBuffer2, HEX);
41
  Serial.print("Dynamic buffer 3 of ");
42
  Serial.print(arraysize * sizeof(uint32_t));
43
  Serial.print(" bytes created, address: 0x");
44
  Serial.println((uintptr_t)dataBuffer3, HEX);
45
  Serial.print("Dynamic buffer 4 of ");
46
  Serial.print(arraysize * sizeof(uint32_t));
47
  Serial.print(" bytes created, address: 0x");
48
  Serial.println((uintptr_t)dataBuffer4, HEX);
49
  Serial.print("Dynamic buffer 5 of ");
50
  Serial.print(arraysize * sizeof(uint32_t));
51
  Serial.print(" bytes created, address: 0x");
52
  Serial.println((uintptr_t)dataBuffer5, HEX);
53
  Serial.print("Dynamic buffer 6 of ");
54
  Serial.print(arraysize * sizeof(uint32_t));
55
  Serial.print(" bytes created, address: 0x");
56
  Serial.println((uintptr_t)dataBuffer6, HEX);
57
  Serial.print("Dynamic buffer 7 of ");
58
  Serial.print(arraysize * sizeof(uint32_t));
59
  Serial.print(" bytes created, address: 0x");
60
  Serial.println((uintptr_t)dataBuffer7, HEX);
61

62
  
63
  for (size_t i=0; i<arraysize; ++i)
64
  {
65
    dataBuffer1[i] = i*2;
66
    dataBuffer2[i] = i*2;
67
    dataBuffer3[i] = i*2;
68
    dataBuffer4[i] = i*2;
69
    dataBuffer5[i] = i*2;
70
    dataBuffer6[i] = i*2;
71
    dataBuffer7[i] = i*2;
72
  }
73
  Serial.println();
74
  Serial.println();
75
/*
76
  Serial.println("Data Buffer 1");
77
  for (size_t i=0; i<arraysize; i+=4)
78
  {
79
    Serial.println();
80
    Serial.print(i, DEC);
81
    Serial.print('\t');
82
    Serial.print(dataBuffer1[i], DEC);
83
    Serial.print('\t');
84
    Serial.print(dataBuffer1[i+1], DEC);
85
    Serial.print('\t');
86
    Serial.print(dataBuffer1[i+2], DEC);
87
    Serial.print('\t');
88
    Serial.print(dataBuffer1[i+3], DEC);
89
  }
90

91
//----------------------------------------*/
92
}
93

94
void loop()
95
{
96
}

edit: hab das ein wenig eingekürzt, alle buffer werden testweise 
ausgegeben, hier aber nur der code für einen
#6929734
Lesenswert?

Programmierer schrieb:
> Genau, Arduino Due hat 96 KM SRAM direkt im uC. Kann genau wie gewohnt
> mit der Arduino IDE programmiert werden. Warum sich mit den antiken
> 8-Bit-Controllern und ihrer schmalen Ausstattung rumplagen, während
> längst wesentlich besser ausgestattete Controller Standard sind...

Das wäre ja einfach...

Mal davon abgesehen dass man mit dem arbeitet was man hat, habe ich 
bisher schon Einiges lernen können.
Erkenntnisgewinn kann auch eine Motivation sein!
#6929835
Lesenswert?

foobar schrieb:
> Ehem, deine dataBuffer1-5 sind auf dem Stack!

Öhm... dann habe ich da wohl etwas grundlegend nicht verstanden.
Ich habe es so verstanden, dass Variablen die mit
1
int buffer[128]
 (ich glaube man sagt dazu statisch) definiert werden kommen in die 
.data-section

https://www.nongnu.org/avr-libc/user-manual/mem_sections.html#sec_dot_data

und die versuche ich ja per Linker-Anweisung in den externen Speicher zu 
schieben
Gast #6929924
Lesenswert?

Bob A. schrieb:
> Da ändert sich leider genau nix wenn ich das Beispiel mit .init1
> verwende
Das sich damit irgendwelche Adressen ändern, hätte ich auch nicht 
erwartet.
Wie auch?

Bob A. schrieb:
> Wie kann ich den startup-code modifizieren,
Das habe ich dir gezeigt!
.ini1 ist schon ein passender Zeitpunkt.

Bob A. schrieb:
>  und das dann auch noch so
> dass es abhängig von der board-Auswahl in der Arduino IDE gemacht wird?
Arduino kennt Boards und Varianten.
Die kannst du selber erstellen und auch die vorhandenen modifizieren.
Hier finden sich die Regeln:
https://arduino.github.io/arduino-cli/0.20/platform-specification/
Gast #6929971
Lesenswert?

Oder so:
(ungetestet, habe keine Erweiterung)
1
  constexpr size_t arraysize = 1024;
2
  
3
  uint32_t dataBuffer1[arraysize];
4
  uint32_t dataBuffer2[arraysize];
5
  uint32_t dataBuffer3[arraysize];
6
  uint32_t dataBuffer4[arraysize];
7
  uint32_t dataBuffer5[arraysize];
8

9

10

11
void setup()
12
{
13

14
  Serial.begin(9600);
15
  
16
  XMCRA |= 1ul<<7; // Switch ext mem iface on
17
  XMCRB = 0;
18
/*------------------------------------
19
  __malloc_heap_start = (char*)0x8000;
20
  __malloc_heap_end   = (char*)0xFFFF;
21
//-------------------------------------*/
22
//*
23
  uint32_t* dataBuffer6 = new uint32_t[arraysize];
24
  uint32_t* dataBuffer7 = new uint32_t[arraysize];
25
//------------------------------------------------*/  
26
/*
27
  uint32_t dataBuffer1[arraysize];
28
  uint32_t dataBuffer2[arraysize];
29
  uint32_t dataBuffer3[arraysize];
30
  uint32_t dataBuffer4[arraysize];
31
  uint32_t dataBuffer5[arraysize];
32
  uint32_t dataBuffer6[arraysize];
33
  uint32_t dataBuffer7[arraysize];
34
//--------------------------------*/
35
  
36
  Serial.println();
37
  Serial.print("Dynamic buffer 1 of ");
38
  Serial.print(arraysize * sizeof(uint32_t));
39
  Serial.print(" bytes created, address: 0x");
40
  Serial.println((uintptr_t)dataBuffer1, HEX);
41
  Serial.print("Dynamic buffer 2 of ");
42
  Serial.print(arraysize * sizeof(uint32_t));
43
  Serial.print(" bytes created, address: 0x");
44
  Serial.println((uintptr_t)dataBuffer2, HEX);
45
  Serial.print("Dynamic buffer 3 of ");
46
  Serial.print(arraysize * sizeof(uint32_t));
47
  Serial.print(" bytes created, address: 0x");
48
  Serial.println((uintptr_t)dataBuffer3, HEX);
49
  Serial.print("Dynamic buffer 4 of ");
50
  Serial.print(arraysize * sizeof(uint32_t));
51
  Serial.print(" bytes created, address: 0x");
52
  Serial.println((uintptr_t)dataBuffer4, HEX);
53
  Serial.print("Dynamic buffer 5 of ");
54
  Serial.print(arraysize * sizeof(uint32_t));
55
  Serial.print(" bytes created, address: 0x");
56
  Serial.println((uintptr_t)dataBuffer5, HEX);
57
  Serial.print("Dynamic buffer 6 of ");
58
  Serial.print(arraysize * sizeof(uint32_t));
59
  Serial.print(" bytes created, address: 0x");
60
  Serial.println((uintptr_t)dataBuffer6, HEX);
61
  Serial.print("Dynamic buffer 7 of ");
62
  Serial.print(arraysize * sizeof(uint32_t));
63
  Serial.print(" bytes created, address: 0x");
64
  Serial.println((uintptr_t)dataBuffer7, HEX);
65
  
66
  for (size_t i=0; i<arraysize; ++i)
67
  {
68
    dataBuffer1[i] = i*2;
69
    dataBuffer2[i] = i*2;
70
    dataBuffer3[i] = i*2;
71
    dataBuffer4[i] = i*2;
72
    dataBuffer5[i] = i*2;
73
    dataBuffer6[i] = i*2;
74
    dataBuffer7[i] = i*2;
75
  }
76
  Serial.println();
77
  Serial.println();
78
/*
79
  Serial.println("Data Buffer 1");
80
  for (size_t i=0; i<arraysize; i+=4)
81
  {
82
    Serial.println();
83
    Serial.print(i, DEC);
84
    Serial.print('\t');
85
    Serial.print(dataBuffer1[i], DEC);
86
    Serial.print('\t');
87
    Serial.print(dataBuffer1[i+1], DEC);
88
    Serial.print('\t');
89
    Serial.print(dataBuffer1[i+2], DEC);
90
    Serial.print('\t');
91
    Serial.print(dataBuffer1[i+3], DEC);
92
  }
93
//----------------------------------------*/
94
}
95
void loop()
96
{
97
}
98

99
void enableExternalMemory() __attribute__((naked,used)) __attribute__((section (".init1"))); 
100
void enableExternalMemory()
101
{
102
  XMCRA = (1<<SRE);
103
  //XMCRA |= (1<<SRE);
104
}
#6930035
Lesenswert?

Oliver S. schrieb:
> Wenn du das Zauberwort schon nennst, dann schreib das auch in den Code.
> Dann klappt das auch mit .data

ich habe das mal so interpretiert dass nur mit "static" deklarierte 
Variablen in .data landen - richtig?
Das hat jetzt genau einmal funktioniert (array-Größe darf dann 
allerdings nicht per Variable zugewiesen werden), alle Versuche das zu 
wiederholen scheitern und es erscheint genau nix im Terminal... Da ist 
doch zum Mäuse melken...
#6930050
Lesenswert?

EAF schrieb:
> Das sich damit irgendwelche Adressen ändern, hätte ich auch nicht
> erwartet.
> Wie auch?

Ich hatte das so verstanden, dass Variablen die so deklariert werden in 
.data landen. Scheinbar ein Trugschluss

> Das habe ich dir gezeigt!
> .ini1 ist schon ein passender Zeitpunkt.

Mir war nicht klar dass ich damit den startup-code ändere. Von den STM32 
kenne ich das eher so, dass es eine separate Datei gibt in der der 
startup-code enthalten ist. So einen Mechanismus wie hier, ich dachte 
das ist was Anderes.
Wieder was gelernt ;)


> Arduino kennt Boards und Varianten.
> Die kannst du selber erstellen und auch die vorhandenen modifizieren.
> Hier finden sich die Regeln:
> https://arduino.github.io/arduino-cli/0.20/platform-specification/

Soweit bin ich auch gekommen, ich habe im sketch-folder ein board 
angelegt und die baords.txt so modifiziert dass es einen Atmega2560 mit 
40k Speicher gibt und in der platform.txt die zusätzlichen Linker-Flags 
hinterlegt.
Das klappt auch so weit.
Ich weiss aber nicht wie ich es anstelle dass der Code zum Einschalten 
der XMEM-Schnittstelle auch automatisch mit der board-Auswahl übernommen 
wird.
#6930103
Lesenswert?

EAF schrieb:
> EAF schrieb:
>> XMCRA |= 1ul<<7; // Switch ext mem iface on
>>   XMCRB = 0;
> Das ist natürlich in meiner setup()  Überflüssig, schadet aber auch
> nicht.

Oliver S. schrieb:
> Was hat wie jetzt genau einmal funktioniert?


ich hatte die buffer als static und fest mit 1024 deklariert. 
Runtergeladen und die buffer hatten andere Adressen.

Dann die beiden Zeilen oben aus setup() entfernt und nix geht mehr.
Mal 'ne Minute von der Versorgungsspannung getrennt und es scheint 
wieder wie gehabt zu funktioniern. fingerscrossed



> Zeig den Code, Compileraufruf, linkeraufruf, etc.
> Und alles bitte als ANHANG.

da ich nicht weiss was genau mit Compileraufruf gemeint ist (wird ja 
öfter aufgerufen), mal der komplette output der Arduino-IDE.
Was genau möchtest du sehen und wie komme ich da ran?

Linker dürfte das hier sein:
1
Linking everything together...
2
"C:\\Users\\xxXXxxXXxx\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-gcc" -Wall -Wextra -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega2560 -Wl,--section-start,.data=0x802200,--defsym=__heap_end=0x80A1FF -o "C:\\Users\\xxXXxxXXxx\\AppData\\Local\\Temp\\arduino_build_504005/xmem-test-2.ino.elf" "C:\\Users\\xxXXxxXXxx\\AppData\\Local\\Temp\\arduino_build_504005\\sketch\\xmem-test-2.ino.cpp.o" "C:\\Users\\xxXXxxXXxx\\AppData\\Local\\Temp\\arduino_build_504005/core\\core.a" "-LC:\\Users\\xxXXxxXXxx\\AppData\\Local\\Temp\\arduino_build_504005" -lm
Angehängte Dateien:
Gast #6930108
Lesenswert?

Bob A. schrieb:
> Ich weiss aber nicht wie ich es anstelle dass der Code zum Einschalten
> der XMEM-Schnittstelle auch automatisch mit der board-Auswahl übernommen
> wird.

In dem du eine eigene variant erstellst.
Dafür gibts ja schließlich den zugehörigen Eintrag in der boards.txt
*.c und *.cpp (evtl auch *.S) Dateien im variants Order werden 
automatisch mit kompiliert.
#6930113
Lesenswert?

EAF schrieb:
> Bob A. schrieb:
>> Ich weiss aber nicht wie ich es anstelle dass der Code zum Einschalten
>> der XMEM-Schnittstelle auch automatisch mit der board-Auswahl übernommen
>> wird.
>
> In dem du eine eigene variant erstellst.
> Dafür gibts ja schließlich den zugehörigen Eintrag in der boards.txt
> *.c und *.cpp (evtl auch *.S) Dateien im variants Order werden
> automatisch mit kompiliert.

Super, Dankeschön!
#6930134
Lesenswert?

EAF schrieb:
> Bob A. schrieb:
>> Dann die beiden Zeilen oben aus setup() entfernt und nix geht mehr.
> Ich hoffe dass du die enableExternalMemory() dabe die nicht vergessen
> hast.

Nee, die war schon noch drin, bzw. eine etwas andere Variante die aber 
auch funktioniert hat.

Aktuell sieht es so aus als ob es funktioniert - evtl sogar schon immer 
funktioniert hat. Nur habe ich falsche Annahmen wegen zu geringem 
Wissensstand gemacht und so wie gedacht hätte es nie funktionieren 
können.

Ich resümiere und bitte um Korrektur wenn ich wieder was nicht kapiert 
habe:

- startup-code kann durch Verwendung von __attribute__(section) 
verändert werden

- selbst wenn .data und .bss im externen Speicher liegen, dann werden 
"normale" Variablen (int foo;) in den Stack lokalisiert

- in .data landen nur Variablen die entweder als static deklariert 
werden oder wie im Beispiel von EAF, arrays die als Größe eine constexpr 
haben

- so wie ich mir das vorgestellt habe, dass einfach alles im externen 
Speicher landet, das geht gar nicht
#6930143
Lesenswert?

Bob A. schrieb:
> - in .data landen nur Variablen die entweder als static deklariert
> werden oder wie im Beispiel von EAF, arrays die als Größe eine constexpr
> haben

Hmm, nee scheint nicht zu stimmen
1
uint32_t someInt;
2
uint32_t someOtherInt = 213;
landen im internen Speicher
1
char err_str[] = "Your program has died a horrible death!";
auch nicht, obschon das das Beispiel von
https://www.nongnu.org/avr-libc/user-manual/mem_sections.html#sec_dot_data 
ist

ich kapiers immer noch nicht was warum wo landet...
#6930154
Lesenswert?

Bob A. schrieb:
> ich kapiers immer noch nicht was warum wo landet...

Tja, nicht immer hilft trail-and-error, machmal muß man lesen und 
lernen.
Dein char[] landet zudem auch noch im Flash ;)

https://www.nongnu.org/avr-libc/user-manual/mem_sections.html

Bob A. schrieb:
> - so wie ich mir das vorgestellt habe, dass einfach alles im externen
> Speicher landet, das geht gar nicht

Für ungenutztes internes SRAm gibts eh kein Geld zurück, also kannst du 
das auch verwenden. Den Stack sollte (oder muß) man da lassen, alles 
andere kann ins externe Ram.

Oliver
#6930166
Lesenswert?

Ok, dann wäre das nächste Vorschlag, ein C-Buch zu lesen. Stichworte 
sind "globale", "statische", "lokale", "automatische" Variable.

Auf der einen Seite machst du da erfolgreich Experimente für 
Fortgeschrittene, auf der anderen Seite fehlen dir die einfachsten 
Grundlagen. Das ist schon eine seltene Mischung ;)

Oliver
#6930212
Lesenswert?

Mjoah.... ich hab den Wink mit dem Scheunentor verstanden :)

Nichtsdestotrotz funzt es jetzt - auch die Integration in die 
Arduino-Welt!

Dank allen Helfern hier!

Ich habe wieder mal viel gelernt - auch wo die eigenen Wissenslücken 
sind. Eigentlich auch ganz wertvoll!

PS:
Damit der automagisch mitkompiliert Code aus dem variants-folder funzt, 
muss man noch
1
#include <avr/io.h>
2
#include <avr/iomxx0_1.h>
einbinden.

Ob das so händisch-hardcoded als eine gute Idee ist?
Aber eigentlich ist es ja fest mit der Variante Atmega2560 verbandelt, 
daher sollte es keine Bedarf geben dass das geändert werden muss.

PPS:
Jetzt muss ich "nur" noch besser verstehen wieso es klappt und warum es 
nicht so geht wie ich anfänglich angenommen hatte.

Danke auch für den Tipp mit dem C-Buch. Werde ich beherzigen!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren