2024-08-16 02:08 AM
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);
}
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?
Solved! Go to Solution.
2024-08-17 12:55 AM
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.
2024-08-16 02:37 PM
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.
2024-08-17 12:55 AM
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.