cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L432 - User Data Flash Write

Nolan L
Associate III
Posted on February 10, 2017 at 18:44

Hi,

I am new to this forum so bearwith me.

We are attempting to store user data in flash on STM32L432 for things such as calibration values for different sensors or CAN ID's so that these values don't need to be hard coded. This would ideally be done through UART.

The issue I have is that my write to flash hangs onthe following line if I place the Flash_write() in a lower part of main():

 if(HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)
�?�?�?

The only difference from where it is successfully being written to flash (function call near top of main() ) and when it fails (function call near bottom of main() ) is a bunch of initialization functions (ADC, DMA, GPIO, I2C, Timers, etc.).

Is there something that is happening in-between that time that I am not accounting for that may hang on HAL_Flash_ex_Erase()?

The following steps are shown to highlight what has been done to successfully write to flash:

Modified Linker Script

/* Specify the memory areas */
MEMORY
{
 RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
 RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 16K
 FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 255K
 DATA (rwx) : ORIGIN = 0x0803F800, LENGTH = 2K /*User Defined Data*/
}
/* Define output sections */
SECTIONS
{
.user_data :
{
 . = ALIGN(4);
 *(.user_data)
 . = ALIGN(4);
} > DATA�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Source Code in C to Write to Flash

#include 'stm32l4xx_hal.h'
#include 'modules/flash/inc/flash.h'
const uint8_t userData[2048] __attribute__((section('.user_data')));
void FLASH_write(FLASH_CONTENT_e content, uint64_t data)
{
 FLASH_EraseInitTypeDef EraseInitStruct;
 uint32_t FirstPage = 0, BankNumber = 0, NbOfPages = 0, PAGEError = 0;
 HAL_FLASH_Unlock();
 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
 switch(content)
 {
 case FLASH_CAN_ID_e:
 FirstPage = 127;
 NbOfPages = 1;
 BankNumber = FLASH_BANK_1;
 break;
 default:
 HAL_FLASH_Lock();
 return;
 }
 EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
 EraseInitStruct.Banks = BankNumber;
 EraseInitStruct.Page = FirstPage;
 EraseInitStruct.NbPages = NbOfPages;
 if(HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)
 {
 //TODO: REMOVE and handle check properly
 while(1);
 }
 if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (uint32_t)&userData[0], data) != HAL_OK)
 {
 //TODO: REMOVE and handle check properly
 while(1);
 }
 HAL_FLASH_Lock();
}
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Main Call Function

int main(void)
{
 /* USER CODE BEGIN 1 */
 /* USER CODE END 1 */
 /* MCU Configuration----------------------------------------------------------*/
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();
 /* Configure the system clock */
 SystemClock_Config();
 FLASH_write(FLASH_CAN_ID_e, 0xABCDEFAB3DEFABCE);
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Notes:

I am using FreeRTOS in this system!

1 ACCEPTED SOLUTION

Accepted Solutions
Nolan L
Associate III
Posted on February 10, 2017 at 23:44

I think I have solved my issue but it will require further testing. I'm positing it here in hopes that it will help other people.

I took off optimization with the C compiler. This lead me to the following line of code indicating the error:

 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR)) {  pFlash.ErrorCode |= HAL_FLASH_ERROR_PGS; }�?�?�?�?

Digging further, I was able to find the answer on this forum:

https://community.st.com/0D50X00009Xki27SAB

  • https://community.st.com/0D50X00009Xki27SAB#comment-81699

    'PGSERR: Programming sequence error

    Set by hardware when a write access to the Flash memory is performed by the code whilethe control register has not been correctly configured. Cleared by writing 1.' My money would be some other bits in the register, like the program bit or the sector number, or you simply haven't cleared the entry/random state for the status/errors. Or an unexpected write has occurred on the array when it's expecting the erase to complete. ie you timed out of the erase and started writing anyway. The JTAG pod can leave the system in a different state than a cold boot. The state of the flash controller should be cleared after you unlock it, before starting a fresh interaction.

I now changed line 14 in my write to flash code to :

__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR | FLASH_FLAG_PGSERR);�?

Again, I will need to conduct further testing but I hope this will help someone.

View solution in original post

10 REPLIES 10
Nolan L
Associate III
Posted on February 10, 2017 at 23:44

I think I have solved my issue but it will require further testing. I'm positing it here in hopes that it will help other people.

I took off optimization with the C compiler. This lead me to the following line of code indicating the error:

 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR)) {  pFlash.ErrorCode |= HAL_FLASH_ERROR_PGS; }�?�?�?�?

Digging further, I was able to find the answer on this forum:

https://community.st.com/0D50X00009Xki27SAB

  • https://community.st.com/0D50X00009Xki27SAB#comment-81699

    'PGSERR: Programming sequence error

    Set by hardware when a write access to the Flash memory is performed by the code whilethe control register has not been correctly configured. Cleared by writing 1.' My money would be some other bits in the register, like the program bit or the sector number, or you simply haven't cleared the entry/random state for the status/errors. Or an unexpected write has occurred on the array when it's expecting the erase to complete. ie you timed out of the erase and started writing anyway. The JTAG pod can leave the system in a different state than a cold boot. The state of the flash controller should be cleared after you unlock it, before starting a fresh interaction.

I now changed line 14 in my write to flash code to :

__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR | FLASH_FLAG_PGSERR);�?

Again, I will need to conduct further testing but I hope this will help someone.

sean green
Associate II
Posted on September 27, 2017 at 17:58

Same thing here using HALL on the stm32f205 chip. My write flash function fails after initialization.

this is my write

void _EEPROM_WRITE(  int offset, uint8_t Data )

{

    HAL_FLASH_Unlock();

    //read and restore the current code.

    static int h[0x3000];

    for (int f=0;f<0x3000;f++)     h[f] = *(__IO uint8_t *)(FLASH_ADDRESS+f);//read

    FLASH_Erase_Sector(FLASH_SECTOR_0, VOLTAGE_RANGE_3);

    for (int t=0;t<0x3000;t++) HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, FLASH_ADDRESS+t, h[t]);//write

    HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, EEPROM_ADDRESS+offset, Data);

    HAL_FLASH_Lock();

}
Posted on September 27, 2017 at 19:06

You should perhaps pay attention to returned status, and clear pending status from the controller.

When erasing this block you're going to want to sure to have SCB->VTOR relocated, and not have any watchdogs running which might cause a reset to occur. Have a Hard Fault handler in case something is going wrong, and identify where precisely it freezes or hangs up.

From a efficiency standpoint would probably do this at a word level, and not mixed bytes and 32-bit ints.

Make sure offset doesn't overlap the region already written, and perhaps consider a more effective way of writing bytes than by erasing/rewriting 0x3000 bytes.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on September 27, 2017 at 19:40

I have a few of those in check here.

1)

I set up my start vector like this.

IROM1:0x08000000 0x00004000  (start up)

IROM2:0x08004000  0x00096000 (default)

This worked as for execution but I could not quite understand why I saw data in sector 0. There are 0x250 some byes in there. I fully expected something in there for a start vector but didn't except this much data. Is copying the bytes to ram and back effective enough to keep the vector intact (SCB->VTOR ).

2)

I do not have any watchdogs running that I know of. I'm also using some middle ware CAN and USB. Removed most of that for a test and had the same issue.

3)

I used 0x3000 to make sure my data does not spill over the sector (leaving 0x1000). Honestly I will never hit > 0x3000. (IBM's famous words I know).

4)

I certainly can set up a return and see if I get an error.  I never used a Hard Fault handler, so will have to look in to that. I see the hard fault is not always the write, it does occur on the FLASH_Erase_Sector (no return for this). Could I have a stack size issue here?

I did plan to use words, agreed that will help but using byte for now until this this is working as it should. Little easier to debug not having to reverse data.

Posted on September 27, 2017 at 20:17

>>IROM1:0x08000000 0x00004000  (start up)

Perhaps describe a region that is truncated so you don't have the linker stepping on your space. Not the cause of the issue.

>>I do not have any watchdogs running that I know of.

Any interrupts? SysTick?

>>Is copying the bytes to ram and back effective enough to keep the vector intact (SCB->VTOR ).

I would say these are two unrelated issues.

>>Could I have a stack size issue here?

Don't think so.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on September 27, 2017 at 20:42

USB does use interrupts but I removed that as a possibility.

SysTick possibly.

    SystemCoreClockUpdate();             

removed this one and issue remains. Took my code down do mainly LEDS and flash writes.

uint8_t buf[2];

  HAL_Init();                           /* Initialize the HAL Library         */

  SystemClock_Config();                 /* Configure the System Clock         */

    device = getDevice();

    device->init();//sets up LED pins

while (1) //usb loop

    {                

_DEBUG( 1);//flashes an LED

    device->probeForGW();//does the flash writes, freezes.

    }

}

.'Perhaps describe a region that is truncated so you don't have the linker stepping on your space. Not the cause of the issue.' - Is that what I see in the beginning of sector 0? Do you mean to truncate like 0x08000000  to 0x00003000  ?

Working in setting up my hard fault code...

sean green
Associate II
Posted on September 28, 2017 at 16:06

Per

Turvey.Clive.002

's advice I'm trying to catch the hardfault. I figured this guide was pretty cut and dry

https://blog.frankvh.com/2011/12/07/cortex-m3-m4-hard-fault-handler/

Though the asm will not compile.

The suggested asm

.syntax unified

.cpu cortex-m3

.thumb

.global HardFault_Handler

.extern hard_fault_handler_c

HardFault_Handler:

TST LR, #4

ITE EQ

MRSEQ R0, MSP

MRSNE R0, PSP

B hard_fault_handler_c

gives many errors.

hardfault.s(1): error: A1158E: Illegal line start, should be blank

hardfault.s(2): error: A1163E: Unknown opcode cortex-m3 , expecting opcode or Macro

hardfault.s(3): error: A1167E: Invalid line start

hardfault.s(5): error: A1163E: Unknown opcode HardFault_Handler , expecting opcode or Macro

hardfault.s(6): error: A1163E: Unknown opcode hard_fault_handler_c , expecting opcode or Macro

hardfault.s(8): error: A1167E: Invalid line start

I've been working this all morning and not getting very far.

Posted on September 28, 2017 at 16:36

 ,

 ,

>,>,I've been working this all morning and not getting very far.

yeah, you seem to be taking weeks to get done what should take an afternoon.

 ,
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on September 28, 2017 at 17:16

Well this is not the only thing being worked on. What I find difficult is how I can search all day for hardware fault examples that do not work and you have 1 example that works perfectly. Maybe that is just being new to ARM processors I don't have this issue in the AVR world. By weeks I think you are referring to the flash/eeprom code. There was some back and forth on that, the clock storage worked out well but after a week the team kicked the battery idea out. The writing to flash also worked out great and we made some progress on the actual code (not frame work). A few weeks later this occurs. After a bit of debugging it turns out something is freezing the code during writes but only after the code loops. This project has lines of USB code, Can code and of course this framework that you have been so help with. So yes I do agree the time table is not inline with my questions but there is more to the project not to mention multiple projects at that.

Anyways, yes this example compiles fine. Though the hard_fault_handler_c is not hit when the halt occurs. Currently the code halts at erasing sector 0 and does not trigger this handler. Going to continue to debug and see what I can figure out.