2016-05-25 8 views
2

Lange Rede kurzer Sinn Ich habe dies in C mit dem IAR-EWARM-Compiler.Zeiger im IAR-Compiler

uint8_t packet[2048]; 
uint32_t* src = (uint32_t*)&packet[9]; 
uint32_t var = *src++; 

Diese letzte Zeile verursacht einen Busfehler.

uint8_t packet[2048]; 
uint32_t* src = (uint32_t*)&packet[9]; 
uint32_t var = 0xFE; 
*src++; 

Jetzt ist kein Busfehler vorhanden. Ich sehe im Debugger src auf die Daten, von denen ich erwarte, dass sie darauf zeigen. Inkrementieren funktioniert wie erwartet, aber der Versuch, es zu lesen, verursacht einen Busfehler.

Irgendwelche Hilfe?

+0

Es ist eine Zusammenstellung von zufälligen Informationsbrocken. Unzureichend nicht nur zum Beantworten, sondern auch zum Verständnis, was gefragt wurde. –

+0

Scheint mir klar. Sie haben einen Prototyp meiner Funktion, Sie können sehen, wie ich den Zeiger referenziere, wenn ich ihn übergebe. Sie haben den eigentlichen Aufruf der Funktion. Und Sie haben die tatsächliche Zeile in der Funktion, wo der Fehler zusammen mit dem tatsächlichen Fehler aufgetreten ist. – lusher00

+0

Nur zur Info - es gibt 3 enge Stimmen, die im Moment unklar sind. –

Antwort

4

Es könnte sein, dass Ihre MCU Lesevorgänge von 32-Bit-Ganzzahlen benötigt, um mit 32 Bits ausgerichtet zu werden.

&packet[9] ist sicherlich nicht 32-Bit-ausgerichtet, deshalb erhalten Sie einen Fehler.

+0

Yup, das ist es. Ich habe alles vergessen. Vielen Dank. – lusher00

4

&packet[9] ist wahrscheinlich nicht korrekt für uint32_t ausgerichtet. Wenn "Bus Error" auf einer ARM-CPU angezeigt wird, ist dies oft ein Zeichen für einen Ausrichtungsfehler. See here für eine Erklärung der Ausrichtung.

Am zweiten Beispiel wird wahrscheinlich der Busfehler vermieden, indem die Operation * optimiert wird, da Sie das Ergebnis nie verwenden.

Beachten Sie, dass selbst wenn Sie dies beheben, der Code immer noch undefiniertes Verhalten verursacht, indem er die strenge Aliasing-Regel verletzt. (uint8_t darf nicht als Alias ​​verwendet werden, wie uint32_t). Einige Compiler scheinen für den Moment "korrekt" zu funktionieren, aber der Code könnte in Zukunft jederzeit brechen.

würde das sicher Äquivalent des Codes sein:

uint8_t *src = &packet[9]; 
uint32_t var; 
memcpy(&var, src, sizeof var); 
src += sizeof var; 

Beachten Sie, dass, wenn die Quelldaten eine bestimmte Byte-Reihenfolge haben für integer angegeben wird (zB Sie es von der Netzstrom zu Daten im Gegensatz bekommen Sie früher mit der gleichen Methode gespeichert), dann möchten Sie eine Methode zum Lesen der Daten verwenden, die unabhängig von der Darstellung von uint32_t ist. (Mit anderen Worten, "Endianness").

Verwandte Themen