Forum: Compiler & IDEs externes SRAM mit 16Bit zugriff


von Star K. (starkeeper)


Lesenswert?

Hi,
ich benutze die GNU tools z.b. arm-elf-gcc um für einen STR710 
programmme zu schreiben.

Ich habe über das externe memory interface des controllers ein SRAM 
angeschlossen. Das SRAM besitzt 4MBit und ist alss 256Kx16Bit 
organisiert. Um also das gesamte memory nutzen zu können will ich mit 
16Bit zugriffen arbeiten.

Nach meinem Verständnis versteckt sich hinter jeder der 256K Adressen 
ein Word mit 16Bit. Das Memory beginnt an Adresse 0x62000000.

Schreibe ich nun mit folgender Zeile ein Word: (sizeof(short) == 16)
*(short*)(0x62000000) = 0xABCD;
wird dies gespeichert allerdings nur in den low Bytes zweier words. Also 
an Adresse 0x62000000 steht 0x00CD und an Adresse 0x62000001 steht 
0x00AB. Ich verschenke also zwei Bytes und greife nicht per word-zugriff 
zu.

Schreibe ich zwei wörter an aufeinanderfolgende Adressen, überschreibe 
ich somit das high byte des vorhergehenden words.

Das externe memory interface meines controllers ist auf 16-Bit Zugriff 
eingestellt.

Ich frage mich ob ich dem arm-elf-gcc nun noch die 16Bit beibringen 
muss, oder ob das eine Linker geschichte ist?

von Andreas K. (a-k)


Lesenswert?

> Ich frage mich ob ich dem arm-elf-gcc nun noch die 16Bit beibringen
> muss, oder ob das eine Linker geschichte ist?

Weder noch. Das hat nichts mit dem Compiler zu tun.

Offenbar stimmt etwas mit der hardwareseitigen Anbindung des Speichers 
(Schaltbild?) oder der Einstellung des Speicherinterfaces vom Controller 
(Code?) nicht.

> Also an Adresse 0x62000000 steht 0x00CD und an Adresse 0x62000001
> steht 0x00AB.

Die Adresse 0x62000001 ist keine Wortadresse, ein Wort-Zugriff darauf 
also nicht zulässig. Die nächste gültige Adresse ist 0x62000002.

Das ganze klingt ein wenig so, als ob der Speicher vom STR als 8 Bit 
breit angesehen wird.

von Andreas K. (a-k)


Lesenswert?

Ein Problem habe ich mit dem STR7. Entweder hat ST den wohl 
industrieweit einzigen absolut fehlerfreien 32bit Microcontroller 
erschaffen (angesichts des STR9 eher unwahrscheinlich), oder sie trauen 
sich nicht die Fehler zu veröffentlichen. Das sonst übliche Errata Sheet 
habe ich jedenfalls nicht gefunden.

von Star K. (starkeeper)


Lesenswert?

Andreas Kaiser wrote:
>> Ich frage mich ob ich dem arm-elf-gcc nun noch die 16Bit beibringen
>> muss, oder ob das eine Linker geschichte ist?
>
> Weder noch. Das hat nichts mit dem Compiler zu tun.
>
> Offenbar stimmt etwas mit der hardwareseitigen Anbindung des Speichers
> (Schaltbild?) oder der Einstellung des Speicherinterfaces vom Controller
> (Code?) nicht.
>
>> Also an Adresse 0x62000000 steht 0x00CD und an Adresse 0x62000001
>> steht 0x00AB.
>
> Die Adresse 0x62000001 ist keine Wortadresse, ein Wort-Zugriff darauf
> also nicht zulässig. Die nächste gültige Adresse ist 0x62000002.
>
> Das ganze klingt ein wenig so, als ob der Speicher vom STR als 8 Bit
> breit angesehen wird.

Den Schaltplan habe ich leider nicht zur Hand momentan, erst wieder 
heute Abend.

Der Zugriff muss doch auch auf eine ungerade Adresse möglich sein. 
Ansonsten kann ich ja nie meinen kompletten SRAM nutzen. Das externe 
memory interface des STR ist mit 16 IO-Leitungen an den SRAM angebunden 
und auch als solches im Code eingestellt. Ändere ich den Zugriffsmodus 
von 16Bit uaf 8Bit im entsprechenden STR Register, dann läuft alles wie 
erwartet. Die 16Bit variablen liegen dann flach aufgereiht im RAM. Ich 
kann dann einen Byte access auf jede Adresse machen. 16Bit Wöter können 
aber nur an geraden Addressen abgelegt werden.

Ich denke nicht da der STR nur 32Bit zugriffe erlaubt, was ja der fall 
wäre, wenn ich immer nur jede gerade Adresse zugreifen darf.

Der Speicher scheint in der Tat als 8-Bit breit angesehen zu werden. 
Jedoch ist doch das Vorsehen von adressen und nutzen des richtigen 
Befehls zum speicherzugrif nicht Aufgabe des Prozessors, sondern des 
Kompilers... das meine ich zumindest zu glauben ;-)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das ist ein Verständnisproblem. Adressen werden immer* als Byte-Adressen 
angesehen, auch wenn der angeschlossene Speicher breiter organisiert 
ist.
Daher kannst Du 16-Bit-Wörter nur an geraden Adressen ablegen, Du hast 
ja auch genügend davon (nämlich 512 K Byte-Adressen, also 256 K gerade 
Adressen).

von pschober (Gast)


Lesenswert?

Du musst die Addressleitungen um eins versetzt anschliessen.
Also A1 vom STR7 an A0 vom RAM usw.

Zu den Erratas :
Ich vermute mal, dass die im Datasheet eingearbeitet sind.
Dies würde auch die teilweise blödsinnigen Peripheriefunktionen (AD 
Wandler immer differetiell, Timer lässt sich nur auf 0xfffc setzen, ...) 
erklären.

von Star K. (starkeeper)


Lesenswert?

pschober wrote:
> Du musst die Addressleitungen um eins versetzt anschliessen.
> Also A1 vom STR7 an A0 vom RAM usw.
>
> Zu den Erratas :
> Ich vermute mal, dass die im Datasheet eingearbeitet sind.
> Dies würde auch die teilweise blödsinnigen Peripheriefunktionen (AD
> Wandler immer differetiell, Timer lässt sich nur auf 0xfffc setzen, ...)
> erklären.

Hmm, das kann doch nicht die Lösung sein? Das ist doch wenn dann nur ein 
Hardware work-around, oder hat das schon mal jemand so gemacht? Ich 
schaue mir mal das StarterKit von denen an...


** edit **
Bei genauerer Betrachtung des Schaltplans scheint es tatsächlich so zu 
sein, dass man die erste Adressleitung beim Anschluss eines externen 
RAMs überspringen muss! tz tz tz

von Andreas K. (a-k)


Lesenswert?

>> Du musst die Addressleitungen um eins versetzt anschliessen.
>> Also A1 vom STR7 an A0 vom RAM usw.
>
> Hmm, das kann doch nicht die Lösung sein? Das ist doch wenn dann nur ein
> Hardware work-around, oder hat das schon mal jemand so gemacht? Ich
> schaue mir mal das StarterKit von denen an...

Doch, das stimmt schon was pschober schreibt. Der Speicherbaustein 
adressiert wortweise, der ARM byteweise. A1(STR7) an A0(Speicher) ist 
somit kein Hack, sondern der korrekte Weg.

Wenn du A0(STR7) an A0(Speicher) angeschlossen hasst, passt das in 
Verbindung mit der Arbeitsweise des ARM7 Core genau auf das vor dir 
beschriebene Verhalten.

Wenn dir dieser Verschiebebahnhof aller Ax-Leitungen zu blöd ist: es 
geht auch einfacher. Bisher hast es vermutlich so angeschlossen:
A0(Speicher) = A0(STR7)
...
A17(Speicher) = A17(STR7)

Einfachste Änderung:
A0(Speicher) = A18(STR7)
A1(Speicher) = A1(STR7)
...
A17(Speicher) = A17(STR7)

von Star K. (starkeeper)


Lesenswert?

Dann müsste ich doch den Adressbereich auch noch verändern, in dem ich 
arbeite, oder?

Also wenn ich A18 an A0 anschliesse muss ich den Adressbereich um 
0x40000 verschieben, damit A18 einen High Pegel bekommt. Da ich aber 
High und Low haben will muss ich noch um die halbe Länge meines RAMs 
zurück gehen?

Also einen Offset von 0x40000-0x20000=0x20000 benutzen? Oder stehe ich 
jetzt total auf dem Schlauch?

von Andreas K. (a-k)


Lesenswert?

Nein. Das wo du drauf stehst, ist die Leitung.

Dein RAM hat aus Sicht der CPU 512KB. 2^^19 Bytes. Das heisst, die 
Adressleitungen A0..A18 vom STR7 erfassen den Inhalt vom RAM.

Das RAM selbst hat jedoch technisch gesehen nicht 512K Bytes, sondern 
256K Worte à 16 Bits, verwendet also dafür 18 Adressleitungen. Ob du die 
nun A0..A17 nennst, oder Anton..Rudolf, bleibt dir überlassen. Ebenso 
ist nicht relevant, ob die nun Anton an A1 und Rudolf an A18 
anschliesst, oder umgekehrt, oder in irgendeiner beliebigen anderen 
Ordnung. Denn es kommt stets grad nur so wieder raus, wie du vorher 
reingeschrieben hast.

Die Leitung A0 vom STR7 ist für das RAM nicht relevant. Statt dessen 
sind die WEx-Leitungen dafür zuständig, das/die richtige Byte(s) 
auszuwählen. Da steckt A0 mit drin.

von Star K. (starkeeper)


Lesenswert?

Hmm, also ich hab mich jetzt auf den Patch bezogen, wonach ich die 
Leitung A18 vom STR an A0 klemmen soll.
Es ist auch klar, das es egal ist, welche Leitung ich wo dran klemme, 
solange ich 18 Leitungen nehme, der Adressbereich von 256K ist dadurch 
ja festgelegt. Nur die unterste Adressleitung muss ausgelassen werden, 
da der ARM kein low byte eines words auf einer ungeraden adresse 
verträgt.

Mein Denkfehler lag nun darin zu meinen das ich nur 256Kbyte RAM habe 
dabei sind es ja 512Kbyte. Die letzte Fehlende Adressleitung ist das 
High-Enable Signal des RAMs. Auch hast du recht das es egal ist wie die 
Daten im RAM liegen, da ich durch meinen immer gleich bleibenden Zugriff 
stets die korrekten Daten heraus bekomme.

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.