cancel
Showing results for 
Search instead for 
Did you mean: 

Memory Managament Fault during FLASH_ProgramWord on STM32F405RGT

deamon
Associate

Hi,

during implementation of a bootloader I have encountered a problem.

I'm using stm32 standard peripheral library.

During writing to flash, for example at address: 0x0800C000 or 0x08010000 when the 18th line:

 

FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data) { FLASH_Status status = FLASH_COMPLETE; /* Check the parameters */ assert_param(IS_FLASH_ADDRESS(Address)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(); if(status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to program the new data */ FLASH->CR &= CR_PSIZE_MASK; FLASH->CR |= FLASH_PSIZE_WORD; FLASH->CR |= FLASH_CR_PG; *(__IO uint32_t*)Address = Data; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(); /* if the program operation is completed, disable the PG Bit */ FLASH->CR &= (~FLASH_CR_PG); } /* Return the Program Status */ return status; } static void flashPage(void){ //flash page if collected FlashPage* const page = &gFlData.flashPage; uint32_t addr = page->flashTargetAddress + ((uint32_t)page->pageCounter * FLASH_PAGE_SIZE); page->pageCounter++; DEBUG(DLT_LOG_INFO,"Pc:%d, flashPageAddr:0x%x", page->pageCounter, addr); int sector = FLASH_If_Address2Sector(addr); ASSERT(sector != -1); int ret = 0; do { if(IsSectorErased(sector)) { DEBUG(DLT_LOG_INFO,"eraseSector:%x", sector); #if 0 MEMDUMP(DLT_LOG_INFO, (uint8_t*)0x0800C000, 32); #endif #if 1 ENTER_CRITICAL_SECTION(); FLASH_Unlock(); ret = FlashIf_Erase((uint16_t)sector); FLASH_Lock(); EXIT_CRITICAL_SECTION(); #endif if(ret < 0) { DERROR("erasePage:0x%x, err:%d - ERROR", addr, ret); break; } else{ gFlData.lastErasedSector = sector; DEBUG(DLT_LOG_INFO,"Success erasure"); } } ENTER_CRITICAL_SECTION(); FLASH_Unlock(); ret = FlashIf_Write(addr, page->buff, page->idx); FLASH_Lock(); EXIT_CRITICAL_SECTION(); #endif if(ret < 0) { ERROR("writePage:0x%x, err:%d - ERROR", addr, ret); break; } DEBUG(DLT_LOG_INFO,"L:%x", page->idx); page->idx = 0; }while(false); }
View more

 

is executed, I receive a NMI interrupt, always.

The function 'flashPage' is a main func(at line 30).

The erase at line 54 works perfectly. I have checked it by reading whole sector, byte after byte, and checking if there is different value than 0xFF.

 

Here is some dump from registers during the hard fault:

BFAR: 08010000
MMFAR: 08010000
CFSR: 00000082
HFSR: 00000000
DFSR: 00000008
AFSR: 00000000
SHCSR: 00070001
From CFSR I can see  Data access violation fault  MMFAR valid

 

The uC has 3.3V Vcc.

It doesn't matter whether I use internal HCI or external HSE. Main clock set to 160MHz.

Main power regulator set to PWR_Regulator_Voltage_Scale1 -> so up to 168Mhz -> and again, the page erase works fine.

 

I've checked option bytes, whether there is some write protection enabled, but when I read the WriteProtectionBytes,(FLASH_OB_GetWRP()) I receive 0xFFF, so the write protection is not enabled.

 

Has anyone an idea, what is a source of my issue?

 

1 ACCEPTED SOLUTION

Accepted Solutions

Thanks Bob.

The FLASH_ProgramWord() is called inside WriteIf_write(), which is only an interface. I've just haven't pasted this part of code, thinking, that it is unnecessary.

Anyway, I have find out the issue -> memory management fault is strictly related to MPU or to physical memory mapping, so I've checked whether the MPU is enabled and -> it is.

After that, it was a simple matter of disabling it.

View solution in original post

2 REPLIES 2
Bob S
Super User

The code you show never calls FLASH_ProgramWord().

Are you SURE that is was really an NMI interrupt?  If you don't have any code for any of the memory management IRQs they all will collapse into a single "while(1);" loop.  Using the CubeIDE fault analyzer may help figure things out. 

Also, on the F4xx series, the "usage fault", "bus fault" and "memory manager fault" are not enabled by default - you have to explicitly enable them by writing to the SCB->SHCSR register.

Thanks Bob.

The FLASH_ProgramWord() is called inside WriteIf_write(), which is only an interface. I've just haven't pasted this part of code, thinking, that it is unnecessary.

Anyway, I have find out the issue -> memory management fault is strictly related to MPU or to physical memory mapping, so I've checked whether the MPU is enabled and -> it is.

After that, it was a simple matter of disabling it.