Skip to main content
ZYagu.1
Associate
Jun 4, 2021 9:52 AM UTC
Solved

Write and read using Flash memory on STM32F7xx (24 sectors)

I've got the following structure to write to memory:

```

#define FLASH_CONFIG_START_ADDR ((uint32_t) 0x080E0000)

#define FLASH_CONFIG_END_ADDR ((uint32_t) 0x080E0040)

union NVRAM {

Config_t config;

uint8_t data[512];

} DevNVRAM;

```

I've used this code for writing to memory

```

uint32_t l_address = FLASH_CONFIG_START_ADDR;

uint8_t l_index = 0x00;

l_address = FLASH_CONFIG_START_ADDR;

HAL_FLASH_Unlock();

FLASH_Erase_Sector(FLASH_SECTOR_11, VOLTAGE_RANGE_1);

while (l_address < FLASH_CONFIG_END_ADDR)

if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, l_address,

DevNVRAM.data[l_index]) == HAL_OK) {

l_index += 1;

l_address += 1;

}

HAL_FLASH_Lock();

```

and then I simply read from the same block of memory.

```

l_address = FLASH_CONFIG_START_ADDR;

l_index = 0x00;

while (l_address < FLASH_CONFIG_END_ADDR) {

DevNVRAM.data[l_index] = *(uint8_t*) l_address;

l_index += 1;

l_address += 1;

}

```

The problem is the following, after I have read the whole sector, data becomes different, in particular, it is filled with zeros. What is the problem with code?

P.S. How can I get first address of memory blovk in the sector without hard-coddding?

This topic has been closed for replies.
ZYagu.1
ZYagu.1Best answer
Associate
Jun 6, 2021 10:04 AM UTC

The problem was in address declaration. it is actually 0x81C000(viewd in st-link utility)

14 replies

waclawek.jan
Super User
Jun 4, 2021 11:14 AM UTC

Cache-related?

Which STM32 in particular?

How is single-bank/dual-bank set?

JW

ZYagu.1
ZYagu.1Author
Associate
Jun 4, 2021 12:29 PM UTC

STM32F767ZI dual-bank

Tesla DeLorean
Guru
Jun 4, 2021 11:31 AM UTC

Is the data you want to write 64 or 512 bytes long?

Why write as bytes, doesn't this need to be words or double words?​

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
ZYagu.1
ZYagu.1Author
Associate
Jun 4, 2021 12:31 PM UTC

Actual size of data is 14 bytes, FLASH_TYPEPROGRAM_BYTE is allowed according to hal_flash.h

TDK
Jun 4, 2021 2:47 PM UTC

Are you using the union properly and not overwriting data? Does reading the memory in the debugger match what you're reading in your code?

"If you feel a post has answered your question, please click ""Accept as Solution""."
ZYagu.1
ZYagu.1Author
Associate
Jun 5, 2021 1:37 AM UTC

I am using debugger and memory monitoring, looks like writing data to memory is not working​ since union is correct(also have checked with debugger)

TDK
Jun 5, 2021 1:53 AM UTC

You shouldn't be calling FLASH_Erase_Sector directly. You should be calling HAL_FLASHEx_Erase. There are other things you're missing as a result.

"If you feel a post has answered your question, please click ""Accept as Solution""."
ZYagu.1
ZYagu.1Author
Associate
Jun 5, 2021 12:41 PM UTC

I have changed the code:

```

static FLASH_EraseInitTypeDef EraseInitStruct;

EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;

EraseInitStruct.Sector = FLASH_CONFIG_START_ADDR;

EraseInitStruct.NbSectors = 0x01;

HAL_FLASH_Unlock();

HAL_FLASHEx_Erase(&EraseInitStruct, &l_error);

```

Now i have this instead of: FLASH_Erase_Sector(FLASH_SECTOR_11, VOLTAGE_RANGE_1);

Unfortunately, this didn't fix the problem, I suppose the problem is with wirting to memory.

TDK
Jun 5, 2021 1:48 PM UTC

> EraseInitStruct.Sector = FLASH_CONFIG_START_ADDR;

This is not a sector value.

Monitor the return values from HAL.

"If you feel a post has answered your question, please click ""Accept as Solution""."
ZYagu.1
ZYagu.1Author
Associate
Jun 6, 2021 5:24 AM UTC

I have tried EraseInitStruct.Sector = FLASH_SECTOR_11; but this didn't help.

Piranha
Principal III
Jun 5, 2021 3:12 PM UTC

By default the FLASH memory is configured as write-through. Because of that cache cleaning is not necessary, but after erasing or programming still a cache invalidation needs to be done on the corresponding FLASH memory addresses. For data memory use SCB_InvalidateDCache_by_Addr() to invalidate D-cache.

ZYagu.1
ZYagu.1Author
Associate
Jun 6, 2021 5:34 AM UTC

I have added SCB_InvalidateDCache_by_Addr(FLASH_CONFIG_START_ADDR, FLASH_CONFIG_END_ADDR - FLASH_CONFIG_START_ADDR);

After Locking Flash. Still didn't fix the problem.

ZYagu.1
ZYagu.1AuthorBest answer
Associate
Jun 6, 2021 10:04 AM UTC

The problem was in address declaration. it is actually 0x81C000(viewd in st-link utility)