Hallo Forengemeinde!
Ich verstehe den AVR-GCC nicht so recht, es geht um folgendes Problem:
Ich habe eine uint32_t-Variable und hole über den UART 4 Byte Daten ab,
welche mir jeweils als uint8_t zur Verfügung stehen. Ich will diese nun
verketten, sodass das zuerst empfangene Byte ganz links (am MSB
sozusagen) in der 32-Bit-Variable steht und von da an abwärts die
Folgebytes.
Das ganze gestaltet sich ungefähr so:
1 | uint32_t registerValue = 0;
|
2 | dataLen = 4;
|
3 | while(dataLen--)
|
4 | {
|
5 | registerValue = registerValue << 8;
|
6 | registerValue |= fifo_get_wait(&FIFO.infifo);
|
7 | }
|
Die fifo_get_wait ist definiert als:
1 | uint8_t fifo_get_wait(fifo_t *f)
|
Gibt also korrekt einen uint8_t zurück.
Das Problem äußert sich darin, dass immer nur das zuletzt gelesene Byte
in registerValue steht, nachdem die Schleife durchlaufen wurde. Die 24
Bit links davon sind 0.
Einzeln kann ich alle 4 Byte empfangen - kann es sein dass ich auf einen
Bug im AVR-GCC gestoßen bin, und der das shiften von 32-Bit-Variablen
nicht richtigmacht?
Ein dazu analoges Programm für x86 auf Windows kompiliert funktioniert:
1 | #include <stdio.h>
|
2 | #include <inttypes.h>
|
3 |
|
4 | uint8_t irgendwas(void) {
|
5 | return 1;
|
6 | }
|
7 |
|
8 | int main(void)
|
9 | {
|
10 | uint32_t test = 0;
|
11 | uint8_t ctr = 2;
|
12 | while (ctr--) {
|
13 | test = test << 8;
|
14 | test |= irgendwas();
|
15 | }
|
16 |
|
17 | printf("%d", test);
|
18 | return 0;
|
19 | }
|
Ergibt wie zu erwarten 257 (0000000100000001).
Hoffe, ihr könnt mir helfen, ich verzweifle hier noch. Was ich schon
versucht habe:
- Den fifo_get_wait-Aufruf auf uint32_t casten
- += statt |= benutzen
- Statt der Shift-Operation *256 rechnen
Was ich ausschließen kann als Fehlerquelle:
- die FIFO funktioniert (alle 4 Byte einzeln empfangen ist kein Problem)
- der UART ist korrekt eingestellt (empfangene Bytes kann ich korrekt
wieder zurücksenden)
- die Hardware (UART-Signale beobachte ich dauerhaft am Logikanalysator
mit)...
Danke für die Hilfe,
Stefan