Forum: Mikrocontroller und Digitale Elektronik C String in uint32 und zurück?


von Alex W. (de1m)


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);

von Peter II (Gast)


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.

von Alex W. (de1m)


Lesenswert?

Peter II schrieb:
> bist du dir sicher mit buf[4]

mein Fehler, habe ich vergessen.

Noch eine Frage, wie ist es wenn
1
buf[32]
 ist, sollte ja genau so gehen oder?

von Peter II (Gast)


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));

von Alex W. (de1m)


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?

von Alex W. (de1m)


Lesenswert?


von Peter II (Gast)


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)

von Peter II (Gast)


Lesenswert?


von Alex W. (de1m)


Lesenswert?


von Peter II (Gast)


Lesenswert?

Alex W. schrieb:
> ah ja, hier aber
> 
https://espressif.com/sites/default/files/documentation/2c-esp8266_non_os_sdk_api_reference_en.pdf

ok, dann musst du nur dafür sorgen, das die länge durch 4 Teilbar ist.
1
spi_flash_write(0x8c000, (uint32*)ssid, sizeof(ssid));
2
spi_flash_read(0x8c000, (uint32*)ssid, sizeof(ssid));

von Alex W. (de1m)


Lesenswert?

okay, danke für die Hilfe ich versuche es morgen weiter.

von Dirk B. (dirkb2)


Lesenswert?

Alex W. schrieb:
> Aber eine Frage noch )
> beim "os_prinf" bekomme ich als Ergebnis "CO2@", hast du vielleicht eine
> Vermutung woher "@" Zeichen kommt?

Peter II schrieb:
> aber nicht die \0. Darfst also keine Stringfunktionen mit dem buf
> aufrufen.

printf mit %s ist auch eine Stringfunktion.

von Nop (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.