If statement wird nicht ausgeführt trotz korrektem Vergleich? (TMS320F28388D)

Gast #6868946
Lesenswert?
• ▲
▼
Hallo zusammen

Auf dem Communication Manager eines TMS320F28388D führe ich den lwIP 
Stack um TCP Packete zu empfangen. Wird ein Packet empfangen kopiert die 
entsprechende Callback-Routine die Daten in einen Puffer `buffer` und 
signalisiert einer Schleife in `main()` mittels flag `command_available` 
dass es Daten zu verarbeiten gibt.

In `main()` wird dann die Routine `processCommand()` aufgerufen welche 
sich das erste Byte von `buffer` anschaut. Ich kann nicht nachvollziehen 
weshalb der if branch niemals ausgeführt wird, obwohl das erste Byte in 
`buffer` 0 ist? (s. dazu auch das angehängte Video einer Debugging 
Session).

Hier sind relevante Codeausschnitte:
1
void processCommand(){
2
    uint8_t command_code=buffer[0];
3
    /*
4
    switch(command_code){
5
        case STOP_ALL:
6
            IPC_sendCommand(IPC_CM_L_CPU1_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
7
                            STOP_ALL, (uint32_t)readData, 0);
8
            IPC_waitForAck(IPC_CM_L_CPU1_R, IPC_FLAG0);
9
            break;
10
        case BUCK_ENABLE_ALL:
11
            IPC_sendCommand(IPC_CM_L_CPU1_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
12
                            BUCK_ENABLE_ALL, (uint32_t)readData, 0);
13
            IPC_waitForAck(IPC_CM_L_CPU1_R, IPC_FLAG0);
14
            break;
15
        default:
16
            break;
17
    }
18
    */
19
    if(command_code==(uint8_t)(0)){
20
        IPC_sendCommand(IPC_CM_L_CPU1_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
21
                        STOP_ALL, (uint32_t)readData, 0);
22
        IPC_waitForAck(IPC_CM_L_CPU1_R, IPC_FLAG0);
23
        return;
24
    }
25
    else{
26
        IPC_sendCommand(IPC_CM_L_CPU1_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
27
                        STOP_ALL, (uint32_t)readData, 0);
28
        IPC_waitForAck(IPC_CM_L_CPU1_R, IPC_FLAG0);
29
        return;
30
    }
31
}
1
uint8_t buffer[512];                    //a buffer storing the last received bytes
2
bool command_available=false;           //indicates whether a new command has been received via TCP
Angehängte Dateien:
#6868975
Lesenswert?
• ▲
▼
Norbert schrieb:
> Wie wird denn buffer gefüllt? Interrupt? Volatile!

Hier ist die entsprechende Routine:
1
// TCP received callback function is called when new data was received on COMM_PORT
2
err_t tcp_recvd_cb(void* arg, struct tcp_pcb* tcppcb, struct pbuf* p,err_t err){
3
    //payload being NULL indicated that the TCP connection has been terminated
4
    if(p->payload==NULL||p->len==0){
5
        connection_active=false;
6
        // close the pcb
7
        tcp_close(tcppcb);
8
        // listen to new connections again
9
        tcp_accept(welcoming_socket_pcb,accept_cb);
10
        return ERR_OK;
11
    }
12
    else{
13
        if(err==ERR_OK){
14
            // -- process the data in p , p is NULL if the remote host terminated the connection --
15
            memcpy(buffer,p->payload,p->len);
16
            u16_t bytes_read=p->len;
17
            //indicate that a new command is available for processing in the buffer
18
            command_available=true;
19
            // -- indicate that bytes were read and we are ready to receive more data --
20
            tcp_recved(tcppcb,bytes_read);   //indicate that no_bytes_read were read and we are ready to receive more data
21
            // -- echo the received data back
22
            tcp_write(tcppcb,buffer,bytes_read,TCP_WRITE_FLAG_COPY);
23
            return ERR_OK;
24
        }
25
        else{
26
            //wait forever and preserve debug state
27
            while(1);
28
        }
29
    }
30
}

Lothar M. schrieb:
> DenDen schrieb:
>> kann nicht nachvollziehen weshalb der if branch niemals ausgeführt wird
> Das wird der Compiler wegoptimiert haben, denn der Code macht doch beide
> Male das selbe. Oder wo müsste ich den Unterschied suchen?

Sorry, die Routine müsste eigtl. folgendermassen lauten (die beiden 
branches sind nicht gleich):
1
void processCommand(){
2
    uint8_t command_code=buffer[0];
3
    /*
4
    switch(command_code){
5
        case STOP_ALL:
6
            IPC_sendCommand(IPC_CM_L_CPU1_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
7
                            STOP_ALL, (uint32_t)readData, 0);
8
            IPC_waitForAck(IPC_CM_L_CPU1_R, IPC_FLAG0);
9
            break;
10
        case BUCK_ENABLE_ALL:
11
            IPC_sendCommand(IPC_CM_L_CPU1_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
12
                            BUCK_ENABLE_ALL, (uint32_t)readData, 0);
13
            IPC_waitForAck(IPC_CM_L_CPU1_R, IPC_FLAG0);
14
            break;
15
        default:
16
            break;
17
    }
18
    */
19
    if(command_code==(uint8_t)(0)){
20
        IPC_sendCommand(IPC_CM_L_CPU1_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
21
                        STOP_ALL, (uint32_t)readData, 0);
22
        IPC_waitForAck(IPC_CM_L_CPU1_R, IPC_FLAG0);
23
        return;
24
    }
25
    else{
26
        IPC_sendCommand(IPC_CM_L_CPU1_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
27
                        BUCK_ENABLE_ALL, (uint32_t)readData, 0);
28
        IPC_waitForAck(IPC_CM_L_CPU1_R, IPC_FLAG0);
29
        return;
30
    }
31
}

Das Problem bleibt leider bestehen.
#6868991
Lesenswert?
• ▲
▼
Ich weiß nicht inwiefern dein Chip Ähnlichkeiten zum TMS320F2808 hat, 
mit dem hab ich damals in der Diplomarbeit gearbeitet.

Schau dir bitte mal sizeof(char) an. Beim 2808er sind das nämlich 16 
Bit, d.h. der Chip kann keine kleineren Dateneinheiten verarbeiten 
(evtl. Bits einzeln noch)

bei
1
uint8_t command_code=buffer[0];

könnte es also sein, dass du in Wirklichkeit 16 Bits deines Datenstromes 
in command_code speicherst (wobei ich mich dann frage, weshalb es 
überhaupt ein uint8_t gibt, das solle dann nämlich nicht definiert sein 
um solche Fehler zu vermeiden)
Beitrag #6868995 wurde von einem Moderator gelöscht.
#6869006
Lesenswert?
• ▲
▼
Christian E. schrieb:
> 0x0011000 = 0x30 = 48 ist der ASCII-Code von '0'.
> Du sendest also "0000" als Text.
>
> Die Variablenvorschau interpretiert wohl char als einen .. Char. Das ist
> das Zeichen '0', nicht die Zahl 0.

Das ist es, vielen Dank!

Der `uint8_t` wird als `unsigned char` definiert weshalb mir die 
Variablenvorschau `0` anzeigt:
1
#elif defined(_TMS320C6X) || defined(__ARM_ARCH) || defined(__ARP32__) || \
2
      defined(__PRU__)    || defined(__C7000__)
3
    typedef   signed char   int8_t;
4
    typedef unsigned char  uint8_t;
5
    typedef          short  int16_t;
6
    typedef unsigned short uint16_t;
7
    typedef          int    int32_t;
8
    typedef unsigned int   uint32_t;

Das Problem ist also nicht der uC Code sondern das Python Skript, 
welches die Daten sendet.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.