[C] Char Array an Funktion übergeben

#3318052
Lesenswert?

Moin,

ich habe eine Methode die mit einem String aufgerufen werden soll, dann 
eine Checksume dranhängt und das ganze per UART von PeterFleury 
versendet.
Das sieht so aus:
1
static char calculate_checksum(char data[]) {
2
    char checksum = 0x00;
3
    for (uint8_t i = 0; i < strlen(data); i++) {
4
        checksum ^= data[i];
5
    }
6
    return checksum;
7
}
8
void send_uart_message(char message[]) {
9
    char checksum = calculate_checksum(message);
10
    char buffer[100];
11
    strcpy(buffer, "$");
12
    strcat(buffer, message);
13
    strcat(buffer, "*");
14
    char checksum_string[2];
15
    sprintf(checksum_string, "%02X", checksum);
16
    strcat(buffer, checksum_string);
17
    strcat(buffer, "\r\n");
18
    uart_puts(buffer);
19
}

Das ganze funktioniert nun, wenn ich es mit
1
send_uart_message("ABC");
aufrufe, ich möchte aber eigentlich soetwas machen, was aber zu einem 
Dauer-Reset führt:
1
char message[120];
2
sprintf(message, "CMP,%d,%d,%d,%d,%d,%d,%d,%d,%d", compass.yaw, compass.pitch,compass.roll, compass.acc_x, compass.acc_y, compass.acc_z,compass.mag_x,compass.mag_y,compass.mag_z);
3
send_uart_message(message);

Wie kann ich das Problem beheben ?
Danke im Voraus !
Gast #3318065
Lesenswert?

Jan H. schrieb:
> char checksum_string[2];
> sprintf(checksum_string, "%02X", checksum);

dein Checksum_string ist zu kurz, checksum kann ja scheinbar bis 255 
werden. Dazu kommt noch das 0 Byte. Also sollte er mindestens 4byte lang 
sein.


> for (uint8_t i = 0; i < strlen(data); i++) {
ist etwas ungünstig, im Zweifelsfall wird stündig strlen aufgerufen.

for( uint8_t i = 0; data[i]; i++) {
Gast #3318081
Lesenswert?

ausßerdem ist ist überhaupt nicht notwendig den string komplett 
zusammenzubauen, kostet nur zeit uns stack.
1
void send_uart_message(char message[]) {
2
    char checksum = calculate_checksum(message);
3
    char checksum_string[3];
4
    sprintf(checksum_string, "%02X", checksum);
5

6
    uart_puts("$");
7
    uart_puts("message");
8
    uart_puts("*");
9
    uart_puts( checksum_string );
10
    uart_puts( "\r\n");
11
}

sollte das gleiche machen, aber etwas weniger speicher brauchen.
#3318089
Lesenswert?

Jo danke nun funzt es, an "\0" hätte ich ja mal denken können -.-
Wundert mich nur, dass es mit "ABC" inkl. Checksumme funktioniert hat.


Peter II schrieb:
> ausßerdem ist ist überhaupt nicht notwendig den string komplett
> zusammenzubauen, kostet nur zeit uns stack.

> sollte das gleiche machen, aber etwas weniger speicher brauchen.


Jo, wo du es sagst...Warum eigentlich nicht !
#3318098
Lesenswert?

Und die Variable i in der Checksum Funktion braucht auch keiner
1
static char calculate_checksum(char data[]) {
2
    char checksum = 0x00;
3

4
    while( *data )
5
      checksum ^= *data++;
6
    }
7

8
    return checksum;
9
}

womit du ganz nebenbei die Beschränkung auf Strings der Maximallänge von 
255 Character losgeworden bist.
#3318102
Lesenswert?

Jan H. schrieb:

> Wundert mich nur, dass es mit "ABC" inkl. Checksumme funktioniert hat.

Das dumme an undefiniertem Verhalten ist, das alles mögliche passieren 
kann. Inklusive dem Verhalten, welches du erwartet hast.
Das bedeutet allerdings nicht, dass es deshalb in Ordnung wäre. 
Fehlerhaft ist fehlerhaft, selbst wenn zufällig das richtige rauskommt, 
weil du zufälig gerade irgendein momentan nicht benutztes Byte im 
Speicher niedergebügelt hast. Bei der nächsten Programmänderung oder 
-erweiterung kann das alles schon wieder ganz anders aussehen.

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