C String in uint32 und zurück?

OP #4684141
Lesenswert?

Hallo Leute,

eine Frage an die C Profis

Es geht um die ESP8266, da kann man bestimmte Infos in flash speichern. 
Es sind die 4KB Blöcke und laut Doku sollte es uint32 sein.
So ich möchte z.B "ABCD" speichern und beim nächsten mal wieder lesen.

Ich habe hier was dazu geschrieben, an sich funktioniert es auch, aber 
ich glaube, dass es kein richtiger Weg ist, wenn ich da etwas mehr habe, 
dann wird es umständlich
1
  uint32 y;
2
  uint32 x;
3

4
  unsigned char buf[4] = "ABCD";
5
    uint32 frostr = buf[0] + 256U*buf[1] + 65536U*buf[2] + 16777216U*buf[3];
6

7
    int i = spi_flash_erase_sector(0x8c);
8
    os_printf("spi_flash_erase_sector: %d\n", i);
9
    int o = spi_flash_write(0x8c000, &frostr, sizeof(x));
10
    os_printf("spi_flash_write: %d\n", o);
11

12
    int p = spi_flash_read(0x8c000, &y, sizeof(y));
13
    os_printf("spi_flash_read: %d\n", p);
14

15
    buf[3] = y >> 24;
16
    buf[2] = y >> 16;
17
    buf[1] = y >> 8;
18
    buf[0] = y;
19

20
    os_printf("read :%s\n", buf);
Gast #4684153
Lesenswert?

ich würde es mit memcpy machen.
1
unsigned char buf[4] = "ABCD";
2
uint32 frostr;
3
memcpy( &frostr, buf, sizeof(frostr) );
4

5
//und zurück
6
unsigned char buf2[4];
7
memcpy( buf, &frostr, sizeof(frostr) );

bist du dir sicher mit buf[4]? Es passen zwar die 4 Buchstaben rein, 
aber nicht die \0. Darfst also keine Stringfunktionen mit dem buf 
aufrufen.
Gast #4684173
Lesenswert?

Alex W. schrieb:
> ist, sollte ja genau so gehen oder?
dafür müsste man mal wissen, wie die Parameter von spi_flash_write 
definiert sind - hast du ein link auf die Doku?

vermutlich kannst du auch einfach so den String übergeben
1
spi_flash_write(0x8c000, (uint32_t*)buf, 4));
OP #4684194
Lesenswert?

danke für die schnelle Hilfe, hat geklappt
So sieht die Funktion aus
1
  uint32 tosave, toread;
2
  char ssid[32];
3
  char ssid2[32];
4

5
  os_memcpy(ssid, "CO2", 3);
6

7
  int i = spi_flash_erase_sector(0x8c);
8
  os_printf("spi_flash_erase_sector: %d\n", i);
9
  int o = spi_flash_write(0x8c000, (uint32*)ssid, sizeof(ssid));
10
  os_printf("spi_flash_write: %d\n", o);
11

12
  int p = spi_flash_read(0x8c000, &toread, sizeof(toread));
13

14
  os_memcpy(ssid2, &toread,sizeof(&toread));
15

16
  os_printf("Read from flash: %s\n", ssid2);

Aber eine Frage noch )
beim "os_prinf" bekomme ich als Ergebnis "CO2@", hast du vielleicht eine 
Vermutung woher "@" Zeichen kommt?
Gast #4684198
Lesenswert?

Alex W. schrieb:
> Vermutung woher "@" Zeichen kommt?

du schreibst sizeof(buf) und liest aber sizeof(int32). Also nur 4 
Zeichen.

Also 2 Fehler. Ersten schreibst du das \0 nicht mit raus. Musst dir also 
irgendwo merken wie lang der String wirklich ist. Und beim Lesen musst 
du halt die länge angeben oder so lange lesen bis \0 kommt (die du aber 
vorher auch schreiben musst)
Gast #4684671
Lesenswert?

Peter II schrieb:
> vermutlich kannst du auch einfach so den String übergeben
> spi_flash_write(0x8c000, (uint32_t*)buf, 4));

Nein, das geht nicht besonders gut, weil buf als array of char zwar 
genauso 4 Bytes belegt wie ein uint32_t, aber buf ist ohne Alignment. 
Wenn die Routine einen uint32_t erwartet, wird sie wohl auch ein 
korrektes alignment erwarten.

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