2013-08-01 01:33 AM
Hi,
I need to store a byte array in the STM32F205 flash memory. I've followed an approach that was working on a STM32F103 mcu, but now it doesn't work anymore.The problem is that the first call to the FLASH_ProgramByte works correctly and returns FLASH_COMPLETE, but int the next iteration of the loop it returns FLASH_ERROR_PROGRAM.My code is the following:#define FLASH_SECTOR_BASE_ADDRESS 0x080c0000
int WriteArray(const uint8_t * dataBuffer, uint32_t dataSize, uint32_t dataAddressOffset){ uint32_t tempAddress; FLASH_Status result; /* Compute temporary address */ tempAddress = FLASH_SECTOR_BASE_ADDRESS + dataAddressOffset; /* Unlock flash memory */ FLASH_Unlock(); /* Clear pending flags (if any) */ FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); /* Copy data into flash memory */ for (uint32_t i = 0; i < dataSize; i++) { /* Program byte */ result = FLASH_ProgramByte(tempAddress, dataBuffer[i]); if (result != FLASH_COMPLETE) { /* Lock flash memory */ FLASH_Lock(); return FALSE; } tempAddress++; } /* Lock flash memory */ FLASH_Lock(); return TRUE;}I've also tried with FLASH_ProgramHalfWord() with an address increment of 2 and with FLASH_ProgramWord() with an address increment of 4, but the problem is the same.Thank you for your helpMarco2013-08-01 04:25 AM
At first glance it doesn't appear unreasonable, are you sure the 128K sector, and specifically the area being written, are erased?
Suggest adding a blank check prior to the write as a sanity check. status = FLASH_EraseSector(FLASH_Sector_10, VoltageRange_3); // 0x080C0000 For 16/32-bit the address needs to be suitably aligned.2013-08-01 06:19 AM
The application starts with a page erase, with a call to FLASH_EraseSector(), then during the main activity the application records some data to the page, using my function WriteArray. When the page is full, the application calls again the FLASH_EraseSector() and so on...
I've added the following code as sanity check before call the FLASH_ProgramByte():/* Do sanity check before write */
tempData = (uint8_t *)tempAddress;if (*tempData != 0xff){/* Lock flash memory */
FLASH_Lock();
return FALSE;
}The code passes always the sanity check, and the tempData variable holds the value 0xff, but the FLASH_ProgramByte() function returns again the FLASH_ERROR_PROGRAM status.2013-08-02 12:19 PM
Do you think calling FLASH_WaitForLastOperation before and after the write operation will help?
From: arkPosted: Thursday, August 01, 2013 3:19 PMSubject: STM32F205 - Store byte array in FLASHThe application starts with a page erase, with a call to FLASH_EraseSector(), then during the main activity the application records some data to the page, using my function WriteArray. When the page is full, the application calls again the FLASH_EraseSector() and so on...
I've added the following code as sanity check before call the FLASH_ProgramByte():/* Do sanity check before write */
tempData = (uint8_t *)tempAddress;if (*tempData != 0xff){/* Lock flash memory */
FLASH_Lock();
return FALSE;
}The code passes always the sanity check, and the tempData variable holds the value 0xff, but the FLASH_ProgramByte() function returns again the FLASH_ERROR_PROGRAM status.2013-08-02 01:13 PM
Do you think calling FLASH_WaitForLastOperation before and after the write operation will help?
I don't think so, the Program routines front and back call WaitForLastOperation. Tossing in additional calls serves no purpose. Something else is in play here, the example isn't sufficiently free standing to demonstrate the failure mode. As it is the ST library dances around a lot with the flash controller, certainly way more than it needs too. I've seen the debugger leave the flash controller in an objectionable state.2013-08-28 04:12 AM
I've noticed a strange behavior: since the software startup the flags PGPERR and PGSERR of the FLASH->SR register are set.
In my procedure, after the FLASH_Unlock() call, I call also the FLASH_ClearFlag() function, but both flags are never cleared! The FLASH_ProgramByte() function fails because the FLASH_WaitForLastOperation() returns the code FLASH_ERROR_PROGRAM.2013-08-28 06:57 AM
Write a minimal and complete applet that demonstrates the failure mode.
You should also be able to test practically identical code on an STM32F4-Discovery board. I'm not going to play guessing games about what software/hardware outside that presented is causing your problems here. Examine initial content of FLASH->CR2013-09-11 01:35 PM
I've checked the initial content of the FLASH->CR register and everything appear to be correct. During other retries i've noticed a strange behavior. If I put a breakpoint after the FLASH_ProgramByte() function to check the result, the code is every time FLASH_ERROR_PROGRAM, and nothing has been writed to the memory. If I put the breakpoint after the FLASH_Lock() function, without interrupting the execution of the write operations, the memory appears to be writed correctly.
Is there any limitations on the debug capabilities while writing the internal flash? I've checked both the reference manual and the errata sheets but there aren't any references to this behavior...I've also tried a similar code on a STM32F103 microcontroller, and everything works perfectly also in step-by-step debug mode.2013-09-11 04:41 PM
My test cases in C and Assembler are working on my F205, so I don't know what the failure mechanisms are for yours, and I can't replicate them.
What compiler are you using? What debugger are you using? Can you run your code from RAM in the debugger? Does turning Off optimization change the functionality? Can you run your code free of a debugger, and just observed debug/diagnostic output? Is there anything interesting/odd about your board?2013-09-12 02:24 AM
I'm using Keil MDK-ARM v.4.72a without optimizations and the Segger J-Link v8.00 debugger with drivers v4.76. The project is based on the Keil RTX OS and has 2 tasks. One read values from a sensor and, in case of the value is over a certain threshold, it writes a record on the flash memory. After each write, correct or incorrect, it writes a message on the ITM port. The other task communicates with an SPI module, but do not interfere with the flash.
My code is running from flash memory, and the microcontroller is an STM32F205ZG revision Y.
If I put a breakpoint in the code between FLASH_Unlock() and FLASH_Lock(), the write fails, while if I remove the breakpoint, on the ITM port I see the correct write message.