moin moin, kleines Problem beim umladen von Speicherwerten. Gegeben: Array a und b mit 8Bytes Pointer x und y auf a[0] und b[0] Sind die Pointer vom Typ DWord werden 4 Byte umgeladen Sind die Pointer vom Typ uint64 gibs ein Fault. Warum? Ist da was "freizuschalten"? Danke Pieter
Bitte den Beispiel Code einstellen und den verwendeten Compiler nennen. Wie ist uint64_t in deinem Toolset deklariert?
ein Fault. Wenn du nicht so faul(t) wärst, hättest du ja den Typ des Faul(t)s dazuschreiben können. Ich würde mal auf mangelndes Alignment tippen. Du bist für QWords vermutlich zu dumm.
Pieter schrieb: > Sind die Pointer vom Typ DWord werden 4 Byte umgeladen Im ARM Kontext ist: - Byte = 8bit - Halfword = 16bit - Word = 32bit - Double Word = 64bit Prüfe die Größen also nochmal, und verwende hier keine Windows Begriffe... Datentypen mit "word" im Namen gibt's in C auch nicht, also wenn schon short, int, long... Pieter schrieb: > Warum? Vielleicht ist der Pointer kein Vielfaches von 4? Das ist bei Double Words erforderlich (alignment).
Pieter schrieb: > Array a und b mit 8Bytes > Pointer x und y auf a[0] und b[0] > > Sind die Pointer vom Typ DWord werden 4 Byte umgeladen > Sind die Pointer vom Typ uint64 gibs ein Fault. > > Warum? Gegenfrage: Warum machst du das? Also warum ist deine Variable als Byte-Arrays definiert, statt direkt als uint64_t? So handelt man sich schnell Alignment-Probleme ein, die genau solche Auswirkungen haben. Du musst also entweder von Hand dafür sorgen, dass dein Array das richtige Alignment hat, oder du nimmst gleich den richtigen Datentyp, dann kümmert sich der Compiler automatisch um das korrekte Alignment.
moin Rolf, die Arrays sind Bestandteil des Datenbuffers vom CAN-Modul und da sind es nunmal Bytes. Umladen mit move ist Byteweise und dauert. Das Umladen als DWord = 4Bytes funktioniert, sind aber auch mehrere Befehle. Daher die Idee es mit QWord = 8Bytes in einem Rutsch zu erledigen. VG Pieter
Pieter schrieb: > Daher die Idee es mit QWord = 8Bytes in einem Rutsch zu erledigen. Wie soll ein CPU Kern mit 32bit Registerbreite 8 bytes in einem Rutsch verarbeiten? Bevor wir es vergessen: benenne den betroffenen Mikrocontroller, zeige den Quelltext, benenne den verwendeten Compiler.
Pieter schrieb: > moin Rolf, > > die Arrays sind Bestandteil des Datenbuffers vom CAN-Modul und da sind > es nunmal Bytes. > Umladen mit move ist Byteweise und dauert. > Das Umladen als DWord = 4Bytes funktioniert, sind aber auch mehrere > Befehle. > Daher die Idee es mit QWord = 8Bytes in einem Rutsch zu erledigen. > > VG > Pieter Umladen, move? Du meinst memcpy?
Kopieren mit unbekanntem (oder nicht passenden) Alignment macht man mit memcpy(). Wenn man ein bestimmtes Alignment erzwingen will, kann man statt des eigentlichen Datentyps eine union deklarieren, die zusätzlich zu dem gewünschten Element noch ein (ansonsten unbenutztes) enthält, daß das gewünschte Alignment hat (in diesem Fall z.B. uint64_t). Das erzwingt das größere Alignment für das (eigentlich gewünschte) Element mit kleinerem Alignment.
Markus F. schrieb: > Wenn man ein bestimmtes Alignment erzwingen will, kann man statt des > eigentlichen Datentyps eine union deklarieren, die zusätzlich zu dem > gewünschten Element noch ein (ansonsten unbenutztes) enthält, daß das > gewünschte Alignment hat (in diesem Fall z.B. uint64_t). > > Das erzwingt das größere Alignment für das (eigentlich gewünschte) > Element mit kleinerem Alignment. Nimmt man da nicht eher alignas?
moin moin, danke für die Beiträge. Da ich in Pascal progge...wer kann Pascal? Stefanus F. schrieb: > Wie soll ein CPU Kern mit 32bit Registerbreite 8 bytes in einem Rutsch > verarbeiten mit LDRD R1, R2, [R0, #0] werden R1+R2 mit dem Inhalt des Speichers mit Zeigers aus R0 geladen. Der Mikrocontroller ist ARM-M3 und und ARM-M4. VG Pieter
Pieter schrieb: > Da ich in Pascal progge...wer kann Pascal? Oha, lang ist's her. Da kam gerade Windows 95 auf den Markt. Pieter schrieb: > mit > LDRD R1, R2, [R0, #0] > werden R1+R2 mit dem Inhalt des Speichers mit Zeigers aus R0 geladen. Interessant, da habe ich etwas dazu gelernt.
Pieter schrieb: > DWord = 4Bytes Nochmal: DWord sind 8 Bytes! Pieter schrieb: > QWord = 8Bytes QWord sind dementsprechend 16 Bytes. Pieter schrieb: > Umladen mit move ist Byteweise und dauert. Move? Du meinst die ARM-Instruktion "mov"? Die verarbeitet Words (=4Byte), kann aber überhaupt nicht auf den Speicher zugreifen. Pieter schrieb: > Der Mikrocontroller ist ARM-M3 und und ARM-M4. Was ist das? Meinst du vielleicht ARM Cortex-M3? Pieter schrieb: > LDRD R1, R2, [R0, #0] Und ist das auch der Code der da rauskommt? R0 ist sicher die korrekte Adresse, welche ein Vielfaches von 4 ist? Pieter schrieb: > Sind die Pointer vom Typ uint64 gibs ein Fault. Was steht dann im CFSR? Ist z.B. das UNALIGNED bit gesetzt? Sicher dass der Fault exakt bei diesem Zugriff geschieht und nicht irgendwann anders?
Dr. Sommer schrieb: > Was ist das? Meinst du vielleicht ARM Cortex-M3? Das war doch wohl klar, oder?
Stefanus F. schrieb: > Das war doch wohl klar, oder? Naja, man darf den verwendeten Prozessor ruhig korrekt benennen, vor allem wenn "ARM M3" eine völlig unübliche Bezeichnung ist. Welcher STM32 es genau ist wissen wir ja auch noch nicht?
moin moin,
>>Welcher STM32 es genau ist wissen wir ja auch noch nicht?
Ist auch nicht nötig, den es geht nur um die CPU-Core.
"The STM32F10xxx is a family of microcontrollers with different memory
sizes, packages and peripherals"
Da darf einer von genommen werden.
Was bringt der genaue Typ?
VG
Pieter
Pieter schrieb: > Was bringt der genaue Typ? Der spezifische Typ könnte Errata haben, der CAN-Controller könnte an einem anderen Bus hängen (APB1/2) welcher sich anders verhält, bei den F103 gibt es Konflikte mit der USB-Peripherie, beim F105 jedoch nicht, usw. Aber wenn du den Typ natürlich geheim halten musst...
Pieter schrieb: > Was bringt der genaue Typ? Pieter schrieb: > Ist da was "freizuschalten"? Wenn da etwas freigeschaltet werden kann/muss, dann ist das sicher spezifisch für das bestimmte unbekannte Mikrocontroller Modell.
Pieter schrieb: > Ist auch nicht nötig, den es geht nur um die CPU-Core. Der CPU-Core hat keine Probleme mit LDRD. Da gibt's nichts freizuschalten; es muss nur die korrekte Adresse und Alignment beachtet werden. Das Problem liegt also am Peripheriebus oder der Peripherie selbst, oder sowieso ganz woanders.
Die Richtige Lösung des Problems wurde in der 4. Antwort genannt: Der besagte Buffer muss als uint64_t definiert sein wenn man in dieser Weise drauf zugreifen will, dann weiß man automatisch daß das erforderliche Alignment garantiert ist. Wenn man es außerdem zusätzlich noch als Bytearray braucht macht man ein union.
Bernd K. schrieb: > dann weiß man automatisch daß das > erforderliche Alignment garantiert ist. Da es sich um ein Peripherie-Register handelt, wird die Adresse hartkodiert, weshalb hier nichts garantiert ist. Die CAN-Daten-Register sind allerdings korrekt aligned.
Dr. Sommer schrieb: > Da es sich um ein Peripherie-Register handelt, wo steht das? Der OP wollte doch Speicherbereiche "umladen"?
Markus F. schrieb: > wo steht das? Pieter schrieb: > die Arrays sind Bestandteil des Datenbuffers vom CAN-Modul und da sind > es nunmal Bytes. Aber das sind natürlich keine Bytes, sondern zwei 32bit-Register.
Dr. Sommer schrieb: > Pieter schrieb: >> die Arrays sind Bestandteil des Datenbuffers vom CAN-Modul und da sind >> es nunmal Bytes. > > Aber das sind natürlich keine Bytes, sondern zwei 32bit-Register. Das kann alles mögliche sein, auch ein Bereich im ganz normalen SRAM wo die Peripherie dann per DMA drauf zugreift (wie es zum Beispiel bei USB üblich ist) solange der OP nicht sagt welcher gottverdammte Controller das überhaupt sein soll!
Bernd K. schrieb: > auch ein Bereich im ganz normalen SRAM wo > die Peripherie dann per DMA drauf zugreift (wie es zum Beispiel bei USB > üblich ist) Nein. Bei allen STM32F1xx sind das zwei schnöde 32bit-Peripherieregister. Der Knackpunkt ist, ob man bei solchen Peripherieregistern LDRD nutzen kann... Der STM32-CAN kann auch kein DMA.
Bernd K. schrieb: > solange der OP nicht sagt welcher gottverdammte Controller > das überhaupt sein soll! Das ist allerdings wirklich wenig verständlich; er vertraut wohl darauf dass STM32-Kundige wissen, wie das bei allen STM32 aussieht.
Dr. Sommer schrieb: > Bernd K. schrieb: >> solange der OP nicht sagt welcher gottverdammte Controller >> das überhaupt sein soll! > > Das ist allerdings wirklich wenig verständlich; er vertraut wohl darauf > dass STM32-Kundige wissen, wie das bei allen STM32 aussieht. Er hat ja auch erst im 11. Post preisgegeben, dass es um Pascal und nicht um C geht. Warum sollte er also den Controller so schnell preisgeben?.
Dr. Sommer schrieb: > Im ARM Kontext ist: > - Byte = 8bit > - Halfword = 16bit > - Word = 32bit > - Double Word = 64bit Ach was. Das Gelaber hatte ich schon vor 20 Jahren bei den 32 bittigen Fujitsu's und später bei ARM. Es ist einfach nur unsystematisch und deshalb verwendet man so etwas auch besser nicht, sondern hält sich ganz einfach an die herkömmlichen Intel-Begriffe. Und da ist ein WORD eben 16 bittig, DWORD 32 und QWORD 64. Basta. Aber bei ARM findet man weder DWORD noch QWORD, denn dort gibt es eben nur int64 als Datentyp und um ein QWORD zu kriegen, muß ein unsigned davor. Dann hat man das. Was bleibt? (mal abgesehen von der ewigen fruchtlosen Rechthaberei) Es bleibt, daß manche Cores mit unausgerichteten Daten eben doch nicht zurecht kommen oder daß gerade in der Peripherie von ST oftmals übelste Verrenkungen nötig waren, weil selbige in weiten Teilen nur 16 bittig ist. Siehe der USB-RAM beim STM32F103. Zugriff 32bittig, aber nur 16bittig belegt. Scheint bei neueren Cores behoben zu sein, aber gerade bei den älteren Cores hatte ST massiv bei NXP abgekupfert und dabei einiges falsch gemacht, wohl weil ST eben nicht die Informationen von Sharp hatte, die NXP beim Aufkauf der BlueStreaks bekommen hatte. Ist aber ne Weile her. W.S.
W.S. schrieb: > Es ist einfach nur unsystematisch Was ist daran unsystematisch? W.S. schrieb: > verwendet man so etwas auch besser nicht, sondern hält sich ganz einfach > an die herkömmlichen Intel-Begriffe Warum sollte man sich an Intel-Begriffe halten, wenn man ARM programmiert? Im ARMv7M Architecture Reference Manual heißt es: > The ARMv7-M architecture supports the following data types in memory: > Byte 8 bits. > Halfword 16 bits. > Word 32 bits. Warum sollte man irgendeine andere Architektur-Definition nehmen? Den Begriff "Quardword" gibt es hier übrigens nur um Kontext der Vektor-Float-Extensions, VFP und NEON. W.S. schrieb: > denn dort gibt es eben > nur int64 als Datentyp und um ein QWORD zu kriegen, int64 ist aber C-spezifisch, und nicht ARM-spezifisch. Jetzt hast du also Intel-Begriffe und C-Begriffe mit gleichlautenden, aber anders-bedeutenden, ARM-Begriffen vermischt. Hurra. W.S. schrieb: > Siehe der USB-RAM beim STM32F103. Zugriff 32bittig, aber nur > 16bittig belegt Aber nichts unaligned, also keine größeren Probleme.
moin moin, da keiner was wirkliches zum Thema sagen wollte oder konnte, klinke ich mich nun aus. VG Pieter
Pieter schrieb: > moin moin, > > da keiner was wirkliches zum Thema sagen wollte oder konnte, klinke ich > mich nun aus. Lol, was für ein Prachtexemplar von Fragesteller, wie im Lehrbuch. -- Ich bin dafür daß sobald der Threaderöffner anfängt vorsätzlich die Problemlösung selbst zu sabotieren (wie hier in Post 16 geschehen) der ganze Thread kommentarlos gelöscht wird.
Pieter schrieb: > da keiner was wirkliches zum Thema sagen wollte oder konnte, klinke ich > mich nun aus. Was? Beantworte doch erstmal unsere Rückfragen, damit wir uns mit vernünftigen Beiträgen beteiligen können. Du hast es in der Hand!
Pieter schrieb: > Warum? Weil Du ein Alignment-Problem hast. Da Du den Sourcetext nicht zeigen willst, such den genauen Fehler halt selber.
W.S. schrieb: > Dr. Sommer schrieb: >> Im ARM Kontext ist: >> - Byte = 8bit >> - Halfword = 16bit >> - Word = 32bit >> - Double Word = 64bit > > Ach was. > > Das Gelaber hatte ich schon vor 20 Jahren bei den 32 bittigen Fujitsu's > und später bei ARM. Logisch. Seit es 32-Bit-Architekturen gibt, eben. Denn Word bezeichnet die native Breite der Architektur. Das Word ist beim x86 nur deshalb 16 Bit breit, weil der mal als 16-Bit-Architektur angefangen hat und man den Datentyp aus Gründen der Rückwärtskompatibilität nicht geändert hat. Die Bezeichnung gab es übrigens schon, bevor es Intel überhaupt gab. Auf der PDP-10 aus den 60er Jahren beispielsweise war ein Word 36 Bit lang. Es ist einfach nur unsystematisch und deshalb > verwendet man so etwas auch besser nicht, sondern hält sich ganz einfach > an die herkömmlichen Intel-Begriffe. "Herkömmlich" ist wie gesagt, dass Word die native Breite bezeichnet. > Und da ist ein WORD eben 16 bittig, DWORD 32 und QWORD 64. Basta. Aha, "basta"… "was interessiert mich der Rest der Welt, ich nenne einfach alles so wie bei Intel, auch wenn das für andere Architekturen falsch ist".
Jemand schrieb: > i8, i16, i32, i64, etc. wäre auch irgendwie zu einfach und eindeutig. Gibts doch! cstdint / stdint.h und Spaß haben! http://www.cplusplus.com/reference/cstdint/
Mw E. schrieb: > Jemand schrieb: >> i8, i16, i32, i64, etc. wäre auch irgendwie zu einfach und eindeutig. > > Gibts doch! > cstdint / stdint.h und Spaß haben! > http://www.cplusplus.com/reference/cstdint/ Da bricht man sich halt immer die Finger mit den ganzen unterstrich-t. Ich persönlich machs wie die Kernelhacker und hab mir Abkürzungen gemacht wie u8, u16, i16, etc...
Jemand schrieb: > i8, i16, i32, i64, etc. wäre auch irgendwie zu einfach und eindeutig Knallt bei Code von Codegeneratoren, die verwenden dieses Pattern für "normale" int Variablen sehr gerne. Daher verwender der Standard ein paar Zeichen mehr. Das LDRD und STRD auf allen Cortex-M immer bei misalinged address knallen, musste auch ich auf die harte Tour lernen. Bei den "normalen" LDR/STR Befehlen kann man das ja auf ARMv7-M kompatiblen abstellen (bzw. ist das per default abgestellt).
Jim M. schrieb: > > Das LDRD und STRD auf allen Cortex-M immer bei misalinged address > knallen, musste auch ich auf die harte Tour lernen. Wobei allign dabei bedeutet, auf 8Byte Grenze, es werden ja auch 64Bit gelesen. Deshalb auch das beschriebene Verhalten, daß 32Bit Zgriffe funktionierten, aber 64Bit Zugriffe nicht. Irgendwie erinnere ich mich gelesen zu haben, daß GCC diese beiden Befehle nicht verwendet. Hier geht es aber um eine nicht näher genannt Pascal Version. Google bringt dieses Problem übrigens auch mit Keil C in Verbindung.
Jim M. schrieb: > Bei den "normalen" LDR/STR Befehlen kann man das ja auf ARMv7-M > kompatiblen abstellen (bzw. ist das per default abgestellt). Ich schalte das aber lieber ein, denn: Laut C(++) Standard sind solche unaligned Zugriffe verboten. Dass ARMv7M die teilweise erlaubt ist pure Nettigkeit. ARMv6M (Cortex-M0) erlaubt diese überhaupt nicht. Um korrekten und portablen Code zu schreiben, vermeide ich solche Zugriffe, und falls doch einer passiert lass ich mir das per Fault anmeckern. Carl D. schrieb: > Wobei allign dabei bedeutet, auf 8Byte Grenze, es werden ja auch 64Bit > gelesen. Nein, auf 4 Byte Grenze! Carl D. schrieb: > Deshalb auch das beschriebene Verhalten, daß 32Bit Zgriffe > funktionierten, aber 64Bit Zugriffe nicht. Nein, das hat irgendeinen anderen Grund. Carl D. schrieb: > Irgendwie erinnere ich mich gelesen zu haben, daß GCC diese beiden > Befehle nicht verwendet. Doch, tut er. Deshalb auch das lustige Problem, dass bei den kaputten Linker Scripten von ST, bei denen der Stack falsch aligned ist, wenn man eine double Variable per Stack übergibt, man einen Crash bekommt, weil diese per LDRD/STRD zugegriffen wird.
Dr. Sommer schrieb: > Carl D. schrieb: >> Wobei allign dabei bedeutet, auf 8Byte Grenze, es werden ja auch 64Bit >> gelesen. > > Nein, auf 4 Byte Grenze! > > Carl D. schrieb: >> Deshalb auch das beschriebene Verhalten, daß 32Bit Zgriffe >> funktionierten, aber 64Bit Zugriffe nicht. > > Nein, das hat irgendeinen anderen Grund. > > Carl D. schrieb: >> Irgendwie erinnere ich mich gelesen zu haben, daß GCC diese beiden >> Befehle nicht verwendet. > > Doch, tut er. Deshalb auch das lustige Problem, dass bei den kaputten > Linker Scripten von ST, bei denen der Stack falsch aligned ist, wenn man > eine double Variable per Stack übergibt, man einen Crash bekommt, weil > diese per LDRD/STRD zugegriffen wird. Was jetzt, hat LDRD/STRD das von ARM dokumentierte Verhalten, oder hat es das nicht. Ich würde vorschlagen zukünftig sich widersprechende Behauptungen zumindest auf zwei getrennte Posts aufzuteilen.
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.