int to char[] to uint8_t[] to char[]

Gast #4627544
Lesenswert?

Hallo Zusammen,

brauche eure Unterstützung um meinen Knoten im Hirn zu beseitigen.

Zur Historie:
Ich habe ein kleines Sensorboard mit einem ATMega1284p gebaut. Alle 
Sensordaten auf dem Board sind vom Typ int (weil die Temperatur negativ 
sein kann). Ich verwende die Funktion itoa, um die Daten in ein char 
array zu überführen und per BLE (UART) an meine Handy-App zu übertragen, 
was auch wunderbar funktioniert.

Jetzt möchte ich die Daten auf dem Sensorboard noch auf einer 
microSD-Karte aufzeichnen. Hierzu verwende ich die Bib von 
http://www.mikrocontroller.net/articles/AVR_FAT32, was grundlegend auch 
funktioniert. Allerdings verwenden die Bibliotheksfunktionen zum Lesen 
und Schreiben durchweg den Datentyp uint8_t.
Aus file.c:
1
uint8_t ffread(void)
2
void ffwrites( uint8_t *s )

Damit die SD-Kartenfunktionalität in mein bisheriges Programm integriert 
werden kann, brauche ich nun CODE, welcher ein char-array in uint8_t[] 
zum Schreiben und beim Lesen wieder zurück convertiert/castet, um den 
"differ in signdeness" Meldungen zu entgehen.
Mein Knoten besteht nun darin, dass ich mir nicht ganz sicher bin, ob 
ich durch das "hinundhercasten/convertieren" von Datentypen ungewollte 
Probleme bekommen kann bzw ob das nicht eleganter gelöst werden könnte.

Derzeit sieht der CODE wie folgt aus und wird auch ohne Fehlermeldungen 
compiliert (AVR Studio 4.19 Build 730):
1
  char write_buffer[16] = "";
2
  uint8_t read_buffer [16] = "";
3
  uint8_t *ptr_read_buffer = read_buffer;
4

5
  
6
  int temp = -99;          //beispielhaft ausgelesene Temperatur von Sensor
7
  itoa(temp,write_buffer,10);    //wandeln in char array und speichern in write_buffer
8

9
  // ------------------------------
10
  // das array auf 15-Zeichen füllen (für den hier nicht gegebenen Rest meines Programms erforderlich!)
11
  write_buffer[14] = write_buffer[2];
12
  write_buffer[13] = write_buffer[1];
13
  write_buffer[12] = write_buffer[0];
14
  int ii;
15
  for (ii=0;ii<12;ii++){
16
    write_buffer[ii] = '0';
17
  }
18
  write_buffer[15] = '\0';
19

20
  // -> 000000000000-99 in write_buffer
21
  // ------------------------------
22

23
  // zum Schreiben: char -> uint8_t
24
  uint8_t *convert_write_data;
25
  convert_write_data=(uint8_t*) &write_buffer;
26

27
  //schreibe Daten in Datei tempmax_file
28
  write_to_file(tempmax_file, convert_write_data);    // verwendet: void ffwrites( uint8_t *s )
29

30
  //lese geschriebene Daten (Zeichen 0 bis 14) und schreibe diese in read_buffer
31
  read_from_file(tempmax_file, 0, 14, ptr_read_buffer);  // verwendet: uint8_t ffread(void)
32

33
  // Für BLE/UART-Ausgabe: uint8_t -> char
34
  char *convert_read_data;
35
  convert_read_data = (char*) &read_buffer;
36

37

38

39
  debug_string_send("von SDCard gelesen: ");        // eigene Funktion zum Senden von Strings per UART
40
  debug_string_sendln(convert_read_data);          // Funktion wie oben nur mit LF und CR
41

42
  // Ausgabe:
43
  // von SDCard gelesen: 000000000000-99

Der Code funktioniert wie gesagt wie gewollt, allerdings hatte ich 
diesen Fall von "Typumwandlungen" bisher noch nie gebraucht, daher bin 
ich mir unsicher ob das IMMER so funktioniert wie ich mir das erhoffe.

Würde mich sehr freuen wenn mir jemand ein Feedback zukommen lassen 
könnte.


Liebe Grüße
Alex
Gast #4627561
Lesenswert?

Es ist gar keine Konvertierung notwendig. Du machst auch keine, das ist 
eine einfacher Typcast.

so geht es etwas einfacher.
1
write_to_file(tempmax_file, (uint8_t*)&write_buffer );

Die Frage ist, warum man es als Klartext (string) in die Datei schreibt. 
Man könnte auch die int-werte direkt in die Datei schreiben, dann spart 
man sich die ganze Stringumwaldlung.
Gast #4627575
Lesenswert?

Dirk B. schrieb:
> Peter II schrieb:
>> write_to_file(tempmax_file, (uint8_t*)&write_buffer );
>
> Da ist das & zuviel.

eigneltich nicht. write_buffer ist ein Array und kein Pointer. (es geht 
beides).

Merkwürdig finde ich mehr, das write_to_file keine länge mit übergeben 
bekommt.
Gast #4627958
Lesenswert?

Danke für die Antworten, ich werde das gleich mal testen!
Ich habe später auf der SD-Karte neben den Werten auch Text, weshalb ich 
das schlichtweg plump über den Texteditor lesen möchte. Daher alles in 
Strings.

Die Funktion write_to_file bekommt keine Länge (des Strings, wenn das 
gemeint war?), da die darin enthaltene Bibliotheks-Funktion ffwrite so 
lange Zeichen schreibt bis diese auf das '\0'-Zeichen stößt.

Da auf meine Bedenken mit den Typcasts keine Einwände kamen gehe ich mal 
davon aus, dass dieses Vorgehen der gängige Weg ist, den ihr auch 
einschlagen würdet? Wie gesagt, hab das bisher noch nicht gebraucht...


Alex
Gast #4627966
Lesenswert?

Alex schrieb:
> Die Funktion write_to_file bekommt keine Länge (des Strings, wenn das
> gemeint war?), da die darin enthaltene Bibliotheks-Funktion ffwrite so
> lange Zeichen schreibt bis diese auf das '\0'-Zeichen stößt.

ist halt etwas merkwürdig. dann könnte man mit der Funktion keine binary 
Daten schreiben. Da hätte ich erwartet das sie ein char* als Parameter 
hat. Dann würde klar sein, das sie bis zum \0 alles rausschreibt.
Gast #4628393
Lesenswert?

Peter II schrieb:
> wie kommst du darauf das es falsch sein muss?
>
> Es ist beides zulässig.
Weil es verschiedene Dinge sind.
1
&write_buffer
ist die Adresse des Pointers der auf write_buffer zeigt. Dieser liegt 
nun zufaellig an genau der selben adresse wie der Start des Arrays.
1
write_buffer
und
1
&write_buffer[0]
sind hingegen die Adressen des ersten Elemntes von write_buffer.
Das sind verschiedene Sachen. &write_buffer funktioniert, ist aber 
trotzdem falsch, weil es was gaenzlich anderes ist.

Mit folgendem Code wird das Problem deutlicher:
1
#include <stdio.h>
2

3
int main(void)
4
{
5
    int arr[10];
6
    int *p_arr = arr;
7
    
8
    printf("&arr     : %p\n", &arr);
9
    printf("arr      : %p\n", arr);
10
    printf("&arr[0]  : %p\n\n", &arr[0]);
11
    printf("&p_arr   : %p\n", &p_arr);
12
    printf("p_arr    : %p\n", p_arr);
13
    printf("&p_arr[0]: %p\n", &p_arr[0]);
14
    
15
    return 0;
16
}
1
&arr     : 0x74af68afe0f0
2
arr      : 0x74af68afe0f0
3
&arr[0]  : 0x74af68afe0f0
4

5
&p_arr   : 0x74af68afe0e8
6
p_arr    : 0x74af68afe0f0
7
&p_arr[0]: 0x74af68afe0f0
Moderator Persönliche Seite #4628409
Lesenswert?

Peter II schrieb:
> Es ging aber um eine Array und da funktioniert ist.

Aber darum muss man nicht auf so einem kryptischen Mist beharrlich 
bestehen - auch wenn es ausnahmsweise bei einem Array stimmt.

Besser man merkt sich den allgemeinen Fall

   var != &var

und fertig.

Es gibt keinen Grund, ausgerechnet bei Arrays - nur weil es da zufällig 
passt - davon abzuweichen.

Oder nenne bitte einen trifftigen Grund. Ich kenne keinen.
Gast #4628415
Lesenswert?

Frank M. schrieb:
> Es gibt keinen Grund, ausgerechnet bei Arrays - nur weil es da zufällig
> passt - davon abzuweichen.

ich sehe es genau andersrum, warum sollte bei Array vom dem Schema 
abweichen?

int i;
addr = &i;

int ii[12];
addr = &ii;

beides sind variablen und keine Zeiger.

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