Forum: Mikrocontroller und Digitale Elektronik 8051 (nRF24LU1+) mit SDCC Compiler, Problem mit xdata und volatile


von Martin K. (skiko)


Lesenswert?

Hallo!

Ich programmiere mit SDCC unter Eclipse für einen Nordic nRF24LU1+ Chip.
Der Chip kann drahtlos bis zu 32 Byte gebündelt senden/empfangen und 
dies würde ich gerne nutzen.
Beim Empfang werden die Daten innerhalb der RF-Interrupt Routine in ein 
Array gespeichert. Damit sie nicht verloren gehen habe ich das globale 
Array mit volatile definiert. Dies Funtkioniert für ein kleines Array 
mit 8 Bytes. Wenn ich die Größe des Arrays aber auf 32 Bytes ändere 
bekomme ich ein Problem mit dem Speicherplatz und die Fehlermeldung 
"ASlink-Error-Could not get 25 consecutive bytes in internal RAM for 
area DSEG". Um dies zu verhindern habe ich die Variable in den externen 
Speicherbereich verschoben, also mit xdata definiert. Das funktioniert 
einzeln auch ganz gut.
Mein Problem ist jetzt, dass ich wenn ich das Array mit volatile und 
xdata definiere keine Daten mehr korrekt lesen oder schreiben kann.
Also:
1
#define SIZE_PAYLOAD 32
2
3
volatile __xdata uint8_t payload[SIZE_PAYLOAD];
4
__xdata  uint8_t xdata_payload[SIZE_PAYLOAD];
5
volatile uint8_t vola_payload[SIZE_PAYLOAD]; 
6
7
void test(uint8_t senddata)
8
{
9
        //liefert nicht das korrekte zeichen
10
  payload[0]=senddata;
11
  printf_small("PAYload_char: %i  ", payload[0]);
12
13
        //liefert das korrekte zeichen, problem mit interupt zu erwarten
14
  xdata_payload[0]=senddata;
15
  printf_small("xdata: %i  ", xdata_payload[0]);
16
17
        //liefert das korrekte zeichen, aber zuwenig platz in dseg
18
  vola_payload[0]=senddata;
19
  printf_small("volatile: %i\r\n", vola_payload[0]);
20
21
 ...

Hat jemand vielleicht eine Idee was ich da falsch mache oder wo hier ein 
Fehler liegen könnte? Vielleicht verträgt sich die Kombination auch 
nicht mit dem UART Interrupt? Aber wie gesagt einzeln ist es kein 
Problem.
Ich bin für alle Ideen dankbar.

Mfg
Martin

von Bernd N (Gast)


Lesenswert?

Welchen 8x51 verwendest du und wieviel RAM hat dieser ? les dir mal die 
Compilerbeschreibung durch und suche nach XRAM Size. Du mußt dem C 
Compiler schon sagen das dein MC XRAM hat und wo er dieses findet.

von Martin K. (skiko)


Lesenswert?

Ich verwende einen erweiterten 8051 Kern. Mit 256 Bytes internem RAM und 
2048 Bytes externem RAM.
Ich habe Testweise auch xram-loc 0x8000 angegeben. Im .mem File ändert 
sich dadurch garnichts?! Mit xram-size wird laut Kompilerbeschreibung 
nur eine Überprüfung der Größe ermöglicht.

Hab jetzt mit der Ausgabe über UART einige Tests gemacht.
uint8_t und volatile uint8_t Variablen kann ich Ausgeben wenn sie lokal 
global oder in einem Array (lokal oder global) sind.
xdata uint8_t kann ich nur fehlerfrei ausgeben wenn sie lokal und nicht 
in einem Array sind (warum auch immer?). xdata volatile uint8_t kann ich 
garnicht fehlerfrei ausgeben.

Ich habe das gefühl das ich entweder mit der Initialisierung des 
externen Speichers was nicht stimmt oder ich sonst irgendein 
Verständnissproblem hab oder die Compileroptionen irgendwo überschrieben 
werden.

Mein mem File:
Internal RAM layout:
      0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00:|0|0|0|0|0|0|0|0|b|b|b|b|b|b|c|d|
0x10:|d|d|d|d|d|d|d|d|d|g|h|Q|Q|Q|Q|Q|
0x20:|B|B|B|B|T|a|a|a|a|a|a|a|a|a|a|a|
0x30:|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
0x40:|a|a|a|a|a|a|a|a|a|a|a|a|a|a|e|e|
0x50:|e|e|e|e|e|e|f|f|f|f|f|f|f|f|f|f|
0x60:|f|f|i|i|i|i|i|i|i|i|i|i|i|i|i|i|
0x70:|i|i|i|i|i|i|i|i|i|i|i|I|I|I|I|I|
0x80:|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|
0x90:|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|
0xa0:|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|I|
0xb0:|I|I|I|I|I|I|I|I|I|I|I|I|I|S|S|S|
0xc0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xd0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xe0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xf0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0-3:Reg Banks, T:Bit regs, a-z:Data, B:Bits, Q:Overlay, I:iData, 
S:Stack, A:Absolute

Stack starts at: 0xbd (sp set to 0xbc) with 67 bytes available.

Other memory:
   Name             Start    End      Size     Max
   ---------------- -------- -------- -------- --------
   PAGED EXT. RAM                         0      256
   EXTERNAL RAM     0x0000   0x0002       3    65536
   ROM/EPROM/FLASH  0x0000   0x19ab    6572    65536

Noch wer eine Idee?

von Martin K. (skiko)


Lesenswert?

Ok habe noch einige Tests gemacht. Wenn ich eine Adresse angebe zb
1
__xdata __at(0x8010) volatile uint8_t xvol_char[256];
2
__xdata __at(0x8000) uint8_t test_char ;

funktioniert alles. Wie kann ich jetzt aber verhindern das ich mir Daten 
überschreibe? Wenn ich beide an der selben Stelle anlege bekomme ich 
auch keine Warnung oder Fehlermeldung. Ich kann ich den Auagabedateien 
den Speicherbreich 0x8000 auch nicht finden um zu überprüfen was dort 
angelegt wird.

von Linker (Gast)


Lesenswert?

Hast du dem Linker erzählt, wo er das xram findet?

Etwas in dieser Form muss irgendwo konfiguriert werden:
http://sdcc.sourceforge.net/doc/sdccman.html/node48.html

von Martin K. (skiko)


Lesenswert?

DANKE!!!

Mein Fehler war das ich xram-loc nicht dem Linker sondern dem Compiler 
erzählt habe. Darum hat sich an der Memorymap nichts geändert. Jetzt 
schauts besser aus da ich im Mem-File sehe das der Xram erst bei 0x8000 
beginnt und die größe passt mit den definierten Arrays zusammen.

Kann erst am Montag wieder auf der Hardware testen ob damit meine Fehler 
behoben sind aber bin sehr zuversächtlich nachdem sich jetzt endlich was 
getan hat.

Schönen Tag!
Martin

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.