Skip to main content
ZYagu.1
Associate
June 4, 2021
Solved

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

  • June 4, 2021
  • 14 replies
  • 5011 views

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.
Best answer by ZYagu.1

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

14 replies

waclawek.jan
Super User
June 4, 2021

Cache-related?

Which STM32 in particular?

How is single-bank/dual-bank set?

JW

ZYagu.1
ZYagu.1Author
Associate
June 4, 2021

STM32F767ZI dual-bank

Tesla DeLorean
Guru
June 4, 2021

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
June 4, 2021

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

TDK
June 4, 2021

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
June 5, 2021

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
June 5, 2021

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
June 5, 2021

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
June 5, 2021

> 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
June 6, 2021

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

Piranha
Principal III
June 5, 2021

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
June 6, 2021

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
June 6, 2021

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