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?
> 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.
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.
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 ;-)
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).
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.
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
>> 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)
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?
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.