cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H735ZG Flash Memory Operation

sasami
Associate II

I'm developing the STM32H735ZG using IAR EW.

I wanted to design sectors 4-7 of the STM32H735ZG's flash memory as a readable/writable data storage area, so I created it by referring to the reference manual, but I can't read or write data properly.

 

I modified the .icf file as attached, defining sectors 4-7 (0x08080000-0x080fffff) as the data storage area(named MEMORY block).

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__     = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__       = 0x0807FFFF;
define symbol __ICFEDIT_region_RAM_start__     = 0x24000000;
define symbol __ICFEDIT_region_RAM_end__       = 0x2404FFFF;
define symbol __ICFEDIT_region_ITCMRAM_start__ = 0x00000000;
define symbol __ICFEDIT_region_ITCMRAM_end__   = 0x0000FFFF;

define symbol __ICFEDIT_region_MEMORY_start__     = 0x08080000;
define symbol __ICFEDIT_region_MEMORY_end__       = 0x080FFFFF;

/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__   = 0x200;
/**** End of ICF editor section. ###ICF###*/

define memory mem with size = 4G;
define region ROM_region      = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region      = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];
define region ITCMRAM_region  = mem:[from __ICFEDIT_region_ITCMRAM_start__ to __ICFEDIT_region_ITCMRAM_end__];

define region MEMORY_region      = mem:[from __ICFEDIT_region_MEMORY_start__   to __ICFEDIT_region_MEMORY_end__];

define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

define block MEMORY	  with alignment = 8, size = __ICFEDIT_size_cstack__ { readwrite section .memory_section };

initialize by copy { readwrite };
do not initialize  { section .noinit };


place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

place in ROM_region   { readonly };
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };

place in MEMORY_region   { block MEMORY };

I also created a .c file to test sector deletion and data writing/reading.

#define MEM_STARTADDR 0x08080000
__attribute__((section(".memory_section")))uint8_t memHead;

bool eraseSectorData(){
	
	bool result;
	
	
	// delete sector 4~7
	FLASH_EraseInitTypeDef erase;
	erase.TypeErase = FLASH_TYPEERASE_SECTORS;
	erase.Sector = FLASH_SECTOR_4;
	erase.NbSectors = 4;
	erase.VoltageRange = FLASH_VOLTAGE_RANGE_3;
	
	uint32_t eraseAddress;
	
	// delete
	HAL_FLASH_Unlock();
	HAL_FLASHEx_Erase(&erase, &eraseAddress);
	HAL_FLASH_Lock();
	
	if(eraseAddress == 0xffffffff){
		result = TRUE;
	}else{
		result = FALSE;
	}
	
	return result;
}

bool copyTest(){
	
	uint8_t ret;
	uint8_t result;
	
	uint8_t test[64];
	uint8_t getTest[64];
	
	// make test data
	for(int i = 0; i < 64 ;i++){
		test[i] = 0x00 + i;
		getTest[i] = 0x00;
	}
	
	// copy test data
	HAL_FLASH_Unlock();
	for(uint32_t i = 0; i < 64; i++){
		ret = HAL_FLASH_Program(0x00, (uint32_t)(MEM_STARTADDR + i), test[i]);
	}
	
	HAL_FLASH_Lock();
	
	memcpy(getTest, (void*)(MEM_STARTADDR), 64);
	
	if(ret == HAL_OK){
		result = TRUE;
	}else{
		result = FALSE;
	}
	
	return result;
	
}

Sector deletion (eraseSectorData()) works without any problems, but executing copyTest() immediately afterwards causes a HardFault in memcpy().

After investigating, I found:

  • HAL_ERROR continues to be returned by HAL_FLASH_Program(), and checking the memory indicates that data is not being written correctly.
  • It appears that the moment memcpy() is entered, address 0xffffffe9 is referenced, causing an "exception flame" and resulting in a HardFault.

To use sectors 4-7 as the data storage area, are there any settings or program issues that need to be changed other than the .icf file?

(Using Google Translate)

 

5 REPLIES 5
LCE
Principal II

Always check and read what the HAL functions do.

HAL_FLASH_Program() only writes 8 x 32bit words.

1) try with only byte buffer size 32

2) try 1st without the multiple HAL_FLASH_Program() loop, write only 1 buffer once

3) check via programmer if flash was written at all

4) don't use memcpy (unless you're 100% sure what this version is doing), try comparing directly flash and the original write buffer

 

I think it's a bad idea to use this H7's flash blocks for things like this, mainly because of the really big 128 kB block size when erasing. I tried the same and rather switched to using the an external SPI flash (which was on the board anyway).

sasami
Associate II

Thank you for your reply. I followed your advice and changed copytest() to the following, but the flash write on line 28 did not occur. 

(I immediately checked the address value in disassembly, but it showed "----" and could not be obtained, so I concluded that this was the case.)

スクリーンショット 2026-02-09 185448.png

Also, a HardFault occurred when reading(line 33).

 

#pragma location = MEM_STARTADDR
__no_init uint32_t m_addrTest;

bool copyTest(){
	
	uint8_t ret;
	uint8_t result;
/*	
	uint8_t test[64];
	uint8_t getTest[64];
	// make test data
	for(int i = 0; i < 64 ;i++){
		test[i] = 0x00 + i;
		getTest[i] = 0x00;
	}
*/

	uint32_t testWord = 0x12345678;
	uint32_t getTestWord = 0x00000000;
	
	// copy test data
	HAL_FLASH_Unlock();
/*
	for(uint32_t i = 0; i < 64; i++){
		ret = HAL_FLASH_Program(0x00, (uint32_t)(MEM_STARTADDR + i), test[i]);
	}
*/
	ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, (uint32_t)MEM_STARTADDR, testWord);
	HAL_FLASH_Lock();
	
//	memcpy(getTest, (void*)(MEM_STARTADDR), 64);

	getTestWord = m_addrTest;
	
	if(ret == HAL_OK){
		result = TRUE;
	}else{
		result = FALSE;
	}
	
	return result;
	
}

 

By the way, why is the block size of 128KB large? I'd like more details. 

Does this mean that the deletion process takes a long time?Or is the load heavy?

LCE
Principal II

You can only erase complete blocks, so 128 kB.

I don't like this for use as a "quasi EEPROM".

But that depends on your use case.

TDK
Super User

> HAL_FLASH_Program(0x00

You must write the entire flash word at a time. 0x00 is not a valid argument here. It must be FLASH_TYPEPROGRAM_FLASHWORD.

 

> m_addrTest

This variable is never initialized. What is the purpose of "getTestWord = m_addrTest" here?

If you feel a post has answered your question, please click "Accept as Solution".
sasami
Associate II

Thank you. Due to circuit limitations, it is difficult to add additional flash memory. The starting address of m_addrTest is 0x08080000, so I thought I could retrieve the data written with

HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, (uint32_t)MEM_STARTADDR, testWord);

by setting "getTestWord = m_addrTest".

Is there any other good way to retrieve the data?