Skip to main content
Associate
Feb 9, 2026 6:02 AM UTC
Question

STM32H735ZG Flash Memory Operation

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

LCE
Principal III
Feb 9, 2026 7:12 AM UTC

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

sasamiAuthor
Associate
Feb 9, 2026 9:53 AM UTC

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 III
Feb 9, 2026 12:57 PM UTC

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
Feb 9, 2026 2:38 PM UTC

> 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""."
sasamiAuthor
Associate
Feb 12, 2026 7:54 AM UTC

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?