Hallo, ich bin auf ein Problem mit den .hex files gestoßen die mir der GNU RISC-V CrossCompiler 8.3.0 (riscv-none-embed) mit eclipse unter windows erzeugt. Die Programme sollen auf einer risc-v 32bit SOC Eigenentwicklung laufen. Das Problem ist das Konstanten wie z.B. const char values[15] = { 128, 64, 32, 16, 8, 4, 2, 1, 2, 4, 8, 16, 32, 64, 128 }; im erzeugten .hex file in ihrer "nativen" Größe in diesem Fall jeweils als ein byte abgespeichert werden und nicht wie es für mich richtg wäre jeweils erweitert als 4 bytes 32bit word). Mit int oder long funktioniert es wieder, die werden jeweils als 4 bytes gespeichert. Optionen wie z.B. mstrict-align oder malign-data ändern leider nichts. Wenn irgendwie im .hex file gekennzeichnet wäre das jetzt bytes folgen und kein word wäre das super aber ist nicht der Fall. Wie kann ich das hinbekommen? Im Anhang ist mein linker script (denke dort habe ich überall das alignment auf 4 gesetzt). Die Konstanten stehen am Ende von .text und werden vom startup-code in .data kopiert. Danke Christian
Christian G. schrieb: > jeweils als ein byte > abgespeichert werden und nicht wie es für mich richtg wäre jeweils > erweitert als 4 bytes 32bit word). Warum sollte das richtig sein? Warum gibst du sie als byte an, wenn du sie als Wort abgespeichert haben möchtest?
Hmm... Strings funktionieren so schlecht, wenn die einzelnen Zeichen auf 4-Byte aligned sind...
MaWin schrieb: > Warum sollte das richtig sein? ... weil es kein erkennbare Unterscheidung zwischen instructions und den values selber gibt, instructions sind 32bit breit, Datenbus und der Speicher auch. Woher soll der loader sonst wissen ob er jetzt gerade ein byte oder ein word kopieren soll? > Warum gibst du sie als byte an, wenn du sie als Wort abgespeichert haben > möchtest? ... eigentlich habe ich das so verstanden das egal welcher Datentyp dieser immer als 32bit word gespeichert wird, was aber anscheinend nicht stimmt, das erzeugte .hex file ist ja korrekt wenn der Speicher auch als bytes organisiert ist.
> Strings funktionieren so schlecht, wenn die einzelnen Zeichen auf 4-Byte > aligned sind... UTF-32.
Christian G. schrieb: >> Warum gibst du sie als byte an, wenn du sie als Wort abgespeichert haben >> möchtest? > ... eigentlich habe ich das so verstanden das egal welcher Datentyp > dieser immer als 32bit word gespeichert wird Das hast du falsch verstanden. Der Sinn der verschieden großen Integertypen liegt ja u.a. darin, die Speicherplatzbelegung größerer Arrays jeweils auf das Notwendige reduzieren zu können.
:
Bearbeitet durch Moderator
Christian G. schrieb: > Woher soll der loader sonst wissen ob er jetzt gerade ein byte oder ein > word kopieren soll? In der Regel aus dem opcode.
Christian G. schrieb: > Das Problem ist das Konstanten wie z.B. const char values[15] = { 128, > 64, 32, 16, 8, 4, 2, 1, 2, 4, 8, 16, 32, 64, 128 }; im erzeugten .hex > file in ihrer "nativen" Größe in diesem Fall jeweils als ein byte > abgespeichert werden und nicht wie es für mich richtg wäre jeweils > erweitert als 4 bytes 32bit word). Wenn Du ein char-Array anlegst, hast Du ein char-Array. Genau das, was man erwarten würde. Wenn Du was anderes haben willst, solltest Du das hinschreiben.
Christian G. schrieb: > Woher soll der loader sonst wissen ob er jetzt gerade ein byte oder ein > word kopieren soll? Der loader kopiert einfach X Bytes, mit X Z.b. 1643. Den kümmert die Organisation nicht. Einmal X Bytes von Adresse Y im Rom nach Z im RAM. Wobei .... Das gilt für initialisierte Variablen, Konstanten eigentlich nur, wenn der Prozessor nicht einfach aus dem Rom lesen kann. Von daher, ... was möchtest Du? Oder verwechselst Du das mit Parametern einer Funktion, die wirklich mindestens int-Breite haben
A. S. schrieb: > Oder verwechselst Du das mit Parametern einer Funktion, die wirklich > mindestens int-Breite haben Haben sie IMO nicht. Das ist allenfalls üblicherweise so auf CPUs mit mindestens 16 bit und wenn nicht mehr Parameter übergeben werden, als Register dafür im ABI vorhanden sind (Rest über den Stack).
Christian G. schrieb: > Die Programme sollen auf einer risc-v 32bit SOC Eigenentwicklung laufen. > Das Problem ist das Konstanten wie z.B. const char values[15] = { 128, > 64, 32, 16, 8, 4, 2, 1, 2, 4, 8, 16, 32, 64, 128 }; im erzeugten .hex > file in ihrer "nativen" Größe in diesem Fall jeweils als ein byte > abgespeichert werden und nicht wie es für mich richtg wäre jeweils > erweitert als 4 bytes 32bit word). Mit int oder long funktioniert es > wieder, die werden jeweils als 4 bytes gespeichert. Optionen wie z.B. > mstrict-align oder malign-data ändern leider nichts. > Wenn irgendwie im .hex file gekennzeichnet wäre das jetzt bytes folgen > und kein word wäre das super aber ist nicht der Fall. > > Wie kann ich das hinbekommen? Kennt deine RISC-V Eigenentwicklung denn die Assemblerbefehle: LB, LH, LBU und LBH? Die sind zuständig um Bytes und Halfwords (16bit) Daten zu laden, und auf 32 Bits zu erweitern. Der Compiler wird sicher solche Befehle verwenden, wenn du auf Byte Arrays zugreifst. Beim laden des Hexfiles die Daten zu ändern, ist keine gute Idee, dann stimmt ja die nachfolgenden Adressen nicht mehr überein, mit dem was der Kompiler angenommen hat.
Danke für die ganzen Antworten, ich hatte das echt falsch verstanden, klar sind die Befehle um bytes / half words zu laden/schreiben implementiert aber die operieren auf einem 32bit word, ich werde den Speicherzugriff ändern. Danke!
Christian G. schrieb: > aber die operieren auf einem 32bit word, ich werde den > Speicherzugriff ändern. Ich sehe da keinen Widerspruch. Wenn du ein Byte lesen willst, dann liest du halt 32 Bit, nimmst davon dann die richtigen 8 Bits und wirfst den Rest weg. Für Halfwords das gleiche. Es hängt vom Speichersystem ab, ob das fies werden kann (z.B. weil Adressen 0x2002 noch existiert, aber 0x2003 nicht), aber das kann man ja per Architekturdekret verbieten. Ich glaube, das richtige Stichwort ist "alignment": Ein Byte hat ein Alignment von 1, ein Halfword von 2, ein Word von 4 und so weiter.
S. R. schrieb: > Es hängt vom Speichersystem ab, ob das fies werden kann (z.B. weil > Adressen 0x2002 noch existiert, aber 0x2003 nicht), aber das kann man ja > per Architekturdekret verbieten. genau das ist das Problem, es wird versucht von einer Adresse zu lesen die nicht 32bit aligned ist, keine Ahnung ob ich dem compiler das irgendwie per Parameter etc. verbieten kann, denke die einfachere Variante ist das ändern meiner CPU da die sich eh im Entwicklungs- /Test-Stadium befindet. Glaube das Thema ist damit erledigt, Danke an alle.
RISC-V erwartet, dass du words und halfwords auch von 'unaligned' Adressen lesen kannst (beim Schreiben dasselbe). Bei einfachen RISC-V Implementationen wird bei unaligned Zugriff oft einfach ein Interrupt ausgelöst, und das Ganze dann in Software richtig behandelt.
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.