user2636834
user2636834

Reputation: 71

Writing a struct to flash memory

I am having problems writing a struct to flash memory using a microcontroller (cortex-M0 inside nrf58122 SoC). I don't know enough c/c++ to determine if it's a memory management issue or a fundamental lack of understanding of programming.

I have a class with a struct member:

struct settings_t
{   
  uint16_t n;
  uint8_t b;
  bool e;
} settings;

In one of my class methods, I need to write the contents of this struct to flash memory in the microcontroller (no EEPROM available). There are pre-written functions that I call in order to do this---I understand I need to erase a page before writing to it. If I try the following:

settings = {
  constants::n,
  constants::b,
  constants::e
};

Where the values n, b, e are of the correct type, and I follow this definition by:

flashPageErase(PAGE_FROM_ADDRESS(constants::settingsPageAddr));
flashWriteBlock(s, &settings, sizeof(settings));

I get a runtime error (program execution halts, don't have an error code for it) when the flashWriteBlock function executes. However, if I copy the struct first:

settings_t cpy = settings;
flashPageErase(PAGE_FROM_ADDRESS(constants::settingsPageAddr));
flashWriteBlock(s, &cpy, sizeof(settings));

Then it does work. Can anyone shed some insight into this? I can provide more detail as needed.

Upvotes: 2

Views: 3077

Answers (2)

D Krueger
D Krueger

Reputation: 2486

The documentation may not say it, but the implementation shows that both the source and destination must be 32-bit aligned:

int flashWriteBlock( void *dst, const void *src, int cb )
{
    uint32_t *d = dst;
    const uint32_t *s = src;

    /* The rest of the function snipped*/
}

The failure is due to the settings variable being 16-bit aligned. It will have to be forced to 32-bit alignment. How this is done is compiler dependent. The following example works for gcc:

struct settings_t
{   
  uint16_t n;
  uint8_t b;
  bool e;
} __attribute__ ((aligned (4))) settings;

Upvotes: 4

Udo Klein
Udo Klein

Reputation: 6912

If you are talking about an Arduino Uno and related ATMega based controllers you might want to consult the official Arduino Website: Reading and Writing Data Structures to EEPROM. The page contains templates for EEPROM_readAnything and EEPROM_writeAnything.

Upvotes: 1

Related Questions