2021-09-01 03:25 AM
We experience a stalled CPU when accessing (writing) the internal FLASH memory
taskENTER_CRITICAL();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_PROGERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR | FLASH_FLAG_PGSERR | FLASH_FLAG_MISERR | FLASH_FLAG_FASTERR | FLASH_FLAG_RDERR | FLASH_FLAG_OPTVERR | FLASH_FLAG_PEMPTY);
// Search me why this bit is checked by STM HAL LIBRARY prior to writing, but it should be 0, otherwise writing cannot happen (thus, clear the bit)
SET_BIT (FLASH->SR, (FLASH_SR_PEMPTY));
// Loop writing until end address is reached
int bufferIndex = 0;
while((_address < _endAddress) && (FLASHStatus == HAL_OK))
{
uint64_t data;
data = (uint64_t)buffer[bufferIndex++];
data = data | (uint64_t)buffer[bufferIndex++] << 32;
FLASHStatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, _address, data);
// 64bit data register requires increment by 8 for next word address
_address = _address + 8;
}
if (FLASHStatus != HAL_OK)
{
returnValue = ERROR;
}
}
taskEXIT_CRITICAL();
This function leads to a stalled CPU (does not restore either, Watchdog must reset the CPU), when I have my UART logger running in parallel. The UART logger is a dedicated task printing strings via UART1, interrupt-based (TXE).
In my code, I disable all interrupts (taskENTER_CRITICAL) prior to accessing the FLASH. But what I see in the registers when the stallment occurs (I access the CPU via STM CubeProgrammer after that happend), is that the TXE and TC bits in the UART1 are set.
So, my guess is, that the logger is busy, the TXE interrupt is serviced (putting a byte on TX pin via the periphery). The ISR is left, and the FLASH write function disables all interrupts. Right after, the UART periphery is finished putting the byte out and raises TXE and TC. What happens at that point?
We are already in contact with an STM field engineer, but up to no, to no avail. This is really driving me nuts
2021-09-10 10:42 AM
Also, yes, disabling RNXE (and maybe even RX in total) would have been a solution. I never ran into this before.
But I learned to handle the ORE in the ISR whenever RXNE is involved as they both are enabled by RXEIE
And I learned that the JLINK is quite a powerful thing
Thanks everyone for support and quick responses!