Hallo zusammen, ich möchte gerade eine SW von einem AVR auf einen ARM (LPC1114) portieren. Soweit so klar. Jetzt wird aber ein void Pointer mehrfach geachtet z.B. von uint8 auf uint16 oder auch uint32. Beim ersten cast passiert nicht und alles ist gut. der 2. cast geht aber in die Hose und der uC wirft einen "hard fault" Irq. Klar jetzt kann ich durch den code gehen und jeden cast raus werfen....aber vielleicht hat ja jemand hier ne Idee wie es besser geht. Gruß Marcel
Marcel schrieb: > aber vielleicht hat ja jemand hier > ne Idee wie es besser geht. Bei Prosa-Coding wie hier Marcel schrieb: > Jetzt wird aber ein void Pointer mehrfach > geachtet z.B. von uint8 auf uint16 oder auch uint32. sicherlich nicht.
Der Unterschied zwischen geraden und ungerade Adressen ist bekannt?
Die Beschreibung ist etwas wirr. Marcel schrieb: > Jetzt wird aber ein void Pointer mehrfach geachtet z.B. von uint8 auf > uint16 oder auch uint32. Wird wirklich der Pointer in uint8 gecastet oder doch eher in einen Pointer auf uint8? > Beim ersten cast passiert nicht und alles ist gut. der 2. cast geht aber > in die Hose und der uC wirft einen "hard fault" Irq. Warum wird der Zeiger denn überhaupt mehrmals gecastet? Tritt der Fehler wirklich beim Cast auf oder erst danach beim Zugriff? Klingt für mich nach einem Misaslignment-Problem. > Klar jetzt kann ich durch den code gehen und jeden cast raus > werfen.... Ja? Kannst du? Warum sind die Casts dann überhaupt drin, wenn die einfach so rausgeworfen werden können? Wenn die wirklich unnötigerweise drin sind, wäre es unabhängig von der Portierung sinnvoll, sie zu entfernen.
Erstmal danke für die Hilfe, also die SW die zu probieren ist ist nicht von mir. Ich hätte das mit Union und struct und entsprechendem Zugriff gelöst. Rauswerfen ist möglich erfordert aber viel bit geschupse.... Naja das mit dem missaligment ist mir jetzt nicht ganz klar. Kann mir da einer kurz auf die Sprünge helfen. Danke und Gruß Marcel
Du hast einen Cortex M0 Prozessorkern, der kann keine unaligned Zugriffe auf Words oder DWords. Aligned heißt, ein word (2 bytes) muß an einer durch 2 teilbaren Adresse liegen und ein dword (4 bytes) an einer durch 4 teilbaren Adresse. Ein 32-Bit Prozessorkern holt sich ja immer 32 bit parallel. Ein unaligned-Zugriff auf ein word oder dword könnte also je nach Adresse bedeuten, daß die Daten aligned sind (d.h. ein 32-bit Zugriff reicht) oder auch nicht (d.h. 2 32-bit Zugriffe nötig). Die Extra-Logik zum Zusammenbauen der Daten im zweiten Fall fehlt beim Cortex M0. Normalerweise sorgt der Compiler dafür, daß die Adressen von Variablen passend aligned sind. Wenn du aber mehrere Byte-Variablen in den Speicher legst, weiß der Compiler von keinem nötigen Alignment und legt die an irgendeine Adresse. Wenn du dann auf word/uint16_t oder dword/uint32_t castest, kann der Zugriff fehlschlagen mit einem hard fault.
:
Bearbeitet durch User
Mach es einfach richtig und trickse nicht herum. Dann ist das Problem gelöst und es kommt nicht 5 Jahren dein Nachfolger und jammert hier wieder. Benutze richtige Datenstrukturen und überlasse dem Compiler den Zugriff. Ein Cast ist Tabu.
Noch eine Info: die Exception bei unaligntem Zugriff gab es bereits vor 30 Jahren bei z.B. dem 68000 (Atari ST, Amiga). Das ist keine Erfindung von heute. Ein erfahrener Programmierer hätte also im Originalcode wohl auch schon darauf verzichtet. Anscheinend war dein Vorgänger nicht so erfahren.
Ah danke für den Hinweis...das der Vortex M0 das nicht kann war mir echt nicht bewußt! Ist mein erster ARM den ich nutze. Habe beruflich nur mit anderen Rechnern zu tun (SPC58xx,V850,...) UND da macht keiner so scheiß mit void pointern 10fach hin und herbiegen! Ne mein Nachfolger wird da mit 100%iger Sicherheit keine Probleme bekommen, ist ne private bastelei :). Wie auch immer ich bau es jetzt so um uint8_t *pointr_pt8; pointr_pt8 = &DaWoDatenHinSollen; *pointr_pt8 = (Data32Bit & 0x000000ff); pointr_pt8++; *pointr_pt8 = (Data32Bit & 0x0000ff00) >> 8; usw.... Erstmal Vielen dank. Marcel
>*pointr_pt8 = (Data32Bit & 0x000000ff); >pointr_pt8++; >*pointr_pt8 = (Data32Bit & 0x0000ff00) >> 8; > >usw.... Aber nur, wen Endianness gleich!
Einfacher ist die Verwendung von memcpy() oder memmove().
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.