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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren