Forum: Compiler & IDEs ARM Arrayzugriff Hardfault


von Markus (Gast)


Lesenswert?

Hallo Community,

ich programmiere gerade eine simple Kommunikation über den ARM M0+ 
SAMC20 von Atmel in dem Atmel Studio 7.

Folgendes Problem:
1
  uint16_t* writeptr =   (uint16_t*)write_data;
2
  uint16_t* readptr = (uint16_t*)DB_get_DBAdress() + startpos;
3
  uint16_t count = 0;
4
  
5
  while (count != n_Register)
6
  {
7
      writeptr[count]  =swap16(readptr[count]);
8
      count++;
9
  }

write_data ist ein Pointer, der der Funktion übergeben ist. Write_data 
Zeigt auf ein Byte in einem Sendepuffer. Diese Daten müssen in das 
Telegramm eingefügt werden, vorher muss die Eandiness geändert werden. 
(swap16)

Außerdem kann write_data auf ein Byte zeigen, welches nicht im 16 bit 
alignment liegt.

Ich suche nun nach einer Möglichkeit dem Compiler dies mitzuteilen. Das 
Programm geht regelmäßig in HardFault.

ARM Information Center sagt:
1
__packed uint32_t* pMyPointer = (__packed uint32_t*)(&tmp)
was jedoch vom Atmel Studio beim Compilieren laut Meldung ignoriert 
wird.

Kann mir jemand die Lösung nennen?

Danke & Gruß

Markus

von Peter II (Gast)


Lesenswert?

Markus schrieb:
> write_data ist ein Pointer, der der Funktion übergeben ist. Write_data
> Zeigt auf ein Byte in einem Sendepuffer

wenn es ein Zeiger auf 8bit ist, darfst du nicht einfach ein Zeiger auf 
16bit daraus machen.

Auch macht es wenig sinn, bei 8 bit die Eandiness zu ändern.

von Markus (Gast)


Lesenswert?

Hallo Peter,

Danke für deine Antwort.

Peter II schrieb:
> wenn es ein Zeiger auf 8bit ist, darfst du nicht einfach ein Zeiger auf
> 16bit daraus machen.
>
> Auch macht es wenig sinn, bei 8 bit die Eandiness zu ändern.




Vielleicht habe ich mich missverständlich ausgedrückt.

Im DB liegen 16 bit Zahlen, bei denen die Eandiness geändert werden 
muss. (Readpointer). Bei diesem Zugriff ist 16bit alignment 
sichergestellt.

Der übergebene Pointer (Write_Data) ist Byte Adressiert, je nach größe 
des Telegrammkopfs liegt dieser im 16bit Raster oder nicht.


Dieses Problem ist einfach zu lösen, indem ich die 16bit Zahl aus dem DB 
lese, schreibe, shifte und schreibe auf 8 bit.
Jedoch muss es eine Möglichkeit geben dem compiler dies zu überlassen. 
Denn: Wenn ich in dieser Funktion direkt auf den Sendepuffer (Bytearray) 
adressiere ohne Variablen, so läuft die Funktion nicht in den Hard Fault 
obwohl das Alignment nicht stimmt.

Diese Möglichkeit suche ich, da mir das Alignment Problem öfters bei den 
ARM´s begegnet. Wahrscheinlich löst das eine bestimmte Syntax zum 
Pointer die ich nicht kenne.


Gruß

Markus

von Blub (Gast)


Lesenswert?

Markus schrieb:
> Der übergebene Pointer (Write_Data) ist Byte Adressiert, je nach größe
> des Telegrammkopfs liegt dieser im 16bit Raster oder nicht.

Und warum? Mach daraus ein 16Bit array und gut isses. Zum Füllen aus 
einem 8Bit Register kannst du casten oder legst ein 8Bit pointer an die 
Startadresse.

von Bernd K. (prof7bit)


Lesenswert?

Markus schrieb:
> je nach größe
> des Telegrammkopfs liegt dieser im 16bit Raster oder nicht.

Und da liegt Dein Problem. Entweder änderst Du das Protokoll so dass 
alles immer ordentlich aligned ist oder Du greifst auf die Bytes einzeln 
zu. Aber wenn Du eh bei jedem Integer das Alignment noch umdrehen musst 
ist das auch kein Geschwindugkeitsnachteil, musst eh alle Bytes einzeln 
anfassen.

von Lothar (Gast)


Lesenswert?

Oder verwende einen Cortex M3 z.B. LPC13 ist auch nicht teurer als der 
SAM M0+ dann haben sich die Alignment Probleme erledigt.

von Bernd K. (prof7bit)


Lesenswert?

Lothar schrieb:
> Oder verwende einen Cortex M3 z.B. LPC13 ist auch nicht teurer als
> der
> SAM M0+ dann haben sich die Alignment Probleme erledigt.

Oh ja, klar das geht auch. Tausch einfach Dein Auto gegen einen LKW ein, 
das ist einfacher als einmal im Jahr die Rückenlehne umzuklappen, dann 
haben sich alle Weihnachtsbaum-Transportprobleme für immer erledigt. Ich 
liebe dieses Formum mit seinen kreativen Ideen ;-)

von Lothar (Gast)


Lesenswert?

Was ist denn das für ein Vergleich. Es gibt kein solches Argument für 
den M0+

Was der an Gates gegenüber dem M3 einspart wird durch mehr Flash für 
mehr Code Speicherbedarf wegen nicht-bedingter Befehlsausführung wieder 
zunichte gemacht.

von Peter II (Gast)


Lesenswert?

Markus schrieb:
> writeptr[count]  =swap16(readptr[count]);

dann macht es ohne die 16bit Funktion
1
uint8_t tmp = readptr[count];
2
writeptr[count] = writeptr[Count+1];
3
writeptr[Count+1] = tmp

aber dann seht es zwar im dem Puffer richtig drin, das hilft aber meist 
nicht weiter, du muss die Daten ja auch verwenden können.

Ich würde einfach eine neue struct anlegen, und die Daten einzeln in die 
Passenden members übernehmen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Lothar schrieb:
> Es gibt kein solches Argument für den M0+

Es gibt kein solches Argument für den M3: unaligned access, egal ob
er nun trapt oder nicht, ist immer Käse, denn es bringt am Ende
Performancenachteile.

Da er in diesem Falle aber sowieso die Bytes verwurschteln muss, gibt
es gar keinen Grund, sie als uint16_t anzusprechen.
1
  uint8_t* writeptr =   (uint8_t*)write_data;
2
  uint8_t* readptr = (uint8_t*)DB_get_DBAdress() + 2 * startpos;
3
  uint_fast16_t count = 0;
4
  
5
  while (count != n_Register)
6
  {
7
      uint8_t tmp = *readptr++;
8
      *writeptr++ = *readptr++;
9
      *writeptr++ = tmp;
10
      count++;
11
  }

Fertig ist die Laube …

: Bearbeitet durch Moderator
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.