0
\$\begingroup\$

Hello everyone,

I am trying to write in the FLASH of my STM32F1, but for some reason it is not working ... Whenever I am programming something, it wil return an error : HAL_FLASH_ERROR_PROG which is a programming error. When I look at it in the flash status register, it means : Set by hardware when an address to be programmed contains a value different from '0xFFFF' before programming.

When I then parse into the FLASH memory of my STM32F1, I see that memory rangin from : 0x801EC00 to 0x801F17F is filled with 0x0000. Hence the Programming error.

What I don't understand is why this part of the memory hasn't been erased. Here is my code :

/* Specify the memory areas */
MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 128K - 5K
Erases (RW)          : ORIGIN = 0x801EC00, LENGTH = 4
Frames (RW)          : ORIGIN = 0x801EC04, LENGTH = 4
FRAMESTx (RW)     : ORIGIN = 0x801EC08, LENGTH = 1400
FRAMESRx (RW)     : ORIGIN = 0x801F180, LENGTH = 1800
FRAMESADC(RW)     : ORIGIN = 0x801F888, LENGTH = 800
FRAMESOP (RW)     : ORIGIN = 0x801FBA8, LENGTH = 800
}


/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

 .nb_Erases : 
 {
    . = ALIGN(4);

      *(.nb_Erases)

    . = ALIGN(4);
    } > Erases

 .nb_Frames : 
 {
    . = ALIGN(4);

      *(.nb_Frames)

    . = ALIGN(4);
    } > Frames

 .user_TramesTx : 
 {
    . = ALIGN(4);

      *(.user_FramesTx)

    . = ALIGN(4);
    } > FRAMESTx

 .user_TramesRx : 
 {
    . = ALIGN(4);

      *(.user_FramesRx)

    . = ALIGN(4);
    } > FRAMESRx

 .user_TramesADC : 
 {
    . = ALIGN(4);

      *(.user_FramesADC)

    . = ALIGN(4);
    } > FRAMESADC

 .user_TramesOp : 
 {
    . = ALIGN(4);

      *(.user_FramesOp)

    . = ALIGN(4);
    } > FRAMESOP

for the linker script

#include "includes.h"

__attribute__((__section__(".nb_Erases"))) const uint32_t Flash_nb_Erases;
__attribute__((__section__(".nb_Frames"))) const uint32_t Flash_nb_Frames;
__attribute__((__section__(".user_TramesTx"))) const CanTxMsgTypeDef CAN_Tab_TxMessages_Flash[50];
__attribute__((__section__(".user_TramesRx"))) const CanRxMsgTypeDef CAN_Tab_RxMessages_Flash[50];
__attribute__((__section__(".user_TramesADC"))) const ADC_TxTypeDef CAN_ADC_Tab_TxMessages_Flash[50];
__attribute__((__section__(".user_TramesOp"))) const CAN_operation Operation_Flash[50];



int Flash_writepreparation(void)
/* Resumé : Function preparing for Flash writing. Unlock flash, clear flags and erase flash.
 *
 * Arguments : none
 *
 * Return : -1 if everything is ok, else : faulty page number
 *
 */
{
     FLASH_EraseInitTypeDef *Erase_Page = NULL;
     uint32_t *Erasing_Error = NULL;


     if (HAL_FLASH_Unlock() != HAL_OK)                                                                                     // We unlock the FLASH to write in it
     {
          return(0);
     }
     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR | FLASH_FLAG_BSY | FLASH_FLAG_OPTVERR );     // Clear of every FLASH flag
     Erase_Page = malloc(sizeof(Erase_Page));                                                                           // Configuration of the Erase_Page structure
     Erasing_Error = malloc(sizeof(Erasing_Error));
     if(Erase_Page == NULL || Erasing_Error == NULL)
     {
          Error_Handler();
     }
     Erase_Page ->TypeErase = FLASH_TYPEERASE_PAGES;
     Erase_Page ->PageAddress =0x801EC00; //ADDRESSE DU DEBUT DE DATA SAUVEGARDE
     Erase_Page ->NbPages = 5;
     HAL_FLASHEx_Erase(Erase_Page , Erasing_Error);                                                                 // We need to erase FLASH to be able to write on it
     if(*Erasing_Error!= 0xFFFFFFFF)
     {
          return(*Erasing_Error);                                                                                          // If there is an error during the erase, Erasing_Error takes the faulty page value
     }
     else
     {
          return(-1);                                                                                                              // -1 = everything is ok
     }

}




int Flash_CANTx_write(CanTxMsgTypeDef *CAN_Tab_TxMessages)
/* Résumé : Function writing CANTx frames in FLASH memory
 *
 * Arguments : CAN_Tab_TxMessages
 *
 * Retourne : 1 if everything is ok, 0 otherwise
 *
 */
{
     uint32_t nb_Erases = 0;
     uint32_t nb_frames_Tx = 0;


     int count_Frames;

     nb_Erases = Flash_nb_Erases + 1;
     nb_frames_Tx = CAN_nb_frames_Tx_cc; //CAN_nb_frames_Tx_cc defined in includes.h

     for (count_Frames= 0 ; count_Frames< nb_frames_Tx ; count_Frames++)
     {
          if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (intptr_t)&CAN_Tab_TxMessages_Flash[count_Frames].DLC, CAN_Tab_TxMessages[count_Frames].DLC) != HAL_OK)     
          {                                                       
               return 0;
          }
          if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (intptr_t)&CAN_Tab_TxMessages_Flash[count_Frames].ExtId, CAN_Tab_TxMessages[count_Frames].ExtId) != HAL_OK)
          {
               return 0;
          }
          if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (intptr_t)&CAN_Tab_TxMessages_Flash[count_Frames].IDE, CAN_Tab_TxMessages[count_Frames].IDE) != HAL_OK)
          {
               return 0;
          }
          if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (intptr_t)&CAN_Tab_TxMessages_Flash[count_Frames].RTR, CAN_Tab_TxMessages[count_Frames].RTR) != HAL_OK)
          {
               return 0;
          }
          if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (intptr_t)&CAN_Tab_TxMessages_Flash[count_Frames].StdId, CAN_Tab_TxMessages[count_Frames].StdId) != HAL_OK)
          {
               return 0;
          }
          if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (intptr_t)&CAN_Tab_TxMessages_Flash[count_Frames].Data[0], CAN_Tab_TxMessages[count_Frames].Data[0]) != HAL_OK)
          {
               return 0;
          }
          if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (intptr_t)&CAN_Tab_TxMessages_Flash[count_Frames].Data[4], CAN_Tab_TxMessages[count_Frames].Data[4]) != HAL_OK)
          {
               return 0;
          }
     }

     if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (intptr_t)&Flash_nb_Erases , nb_Erases ) != HAL_OK)                                                       
     {
          return 0;
     }

     return 1;





}



int Saving_Flash(CanTxMsgTypeDef *CAN_Tab_TxMessages)
/* Résumé : Function saving in FLASH
 *
 * Arguments : CAN_Tab_TxMessages
 *
 * Retourne : 1 if everything is ok, 0 otherwise
 *
 */
{
     int test = 0;

     test = Flash_writepreparation();                                                  

     if (test != -1)
     {
          Error_Handler();
     }

     if(Flash_CANTx_write(CAN_Tab_TxMessages) != 1)                         
     {
          Error_Handler();
     }

     if(HAL_FLASH_Lock() != HAL_OK)                                                       //We need to lock the FLASH at the end
     {
          Error_Handler();
     }

     return 1;



}

The function "Saving_Flash" is the one I call in main.c to save the CAN_Tab_TxMessages in the FLASH. Flash_writepreparation() is supposed to prepare the Flash for being written (unlock, erase the 5 pages, clear the flags). Finally, Flash_CANTx_write writes every frame of the array in the FLASH.

If you have any idea on why HAL_FLASHEx_Erase() is not working ...

Just to add : there is no special warning or error when I build my code.

Thank you in advance !

I've tried to change the address of HAL_FLASH_Program in FLASH_CANTx_Write, to put &CAN_Tab_RxMessages_Flash, now, starting from 0x801F180 to 0x801F888 in the memory buffer is equal to 00000000. So it appears that depending on where I want to write, the address won't erase properly ... But I don't know how to deal with it ..

EDIT : IT IS WORKING ! more or less ... The writing is now functionning but the reading not completely ...

To retrieve the data I wrote in the Flash I am doing this :

__attribute__((__section__(".nb_Frames"))) extern const uint32_t number_Frames_Flash;
__attribute__((__section__(".user_FramesTx"))) extern const CanTxMsgTypeDef CAN_Tab_TxMessages_Flash[50];

[...]

CAN_nb_frames_Tx = (number_Frames_Flash & 0x000000FF);


for(cpt_for = 0 ; cpt_for < CAN_nb_frames_Tx ; cpt_for ++)
{
      CAN_Tab_TxMessages[cpt_for] = CAN_Tab_TxMessages_Flash[cpt_for];
}

Since the number of Tx Frames is stored in the right byte of number_Frames_Flash, I just look at the right byte. But the issue is that CAN_nb_frames_Tx stays = 0 ; whereas if I look at the value of "(number_Frames_Flash & 0x000000FF)" in the debugger, it is equal to the value I expect (i.e the number of Tx Frames). I don't know where it's coming from ...

I am almost done !

\$\endgroup\$
0
\$\begingroup\$

You should not use malloc on an embedded system (unless you wrote a custom malloc?). Looks like you're erasing a different region of memory than you intended.

An example of a similar problem from someone using malloc on an STM32F1:

https://stackoverflow.com/questions/22422733/malloc-behaviour-on-an-embedded-system

\$\endgroup\$
  • \$\begingroup\$ I am using some malloc() in my code, to create dynamic structure arrays and to initialize pointers. Do you have an idea to bypass the use of malloc in that case ? "Looks like you're erasing a different region of memory than you intended." I guess it's something like that that is happening, basically, it erases all of the regions I defined in the linker script, but the ones I am using in the code (.nb_Erases) and (.user_TramesTx) \$\endgroup\$ – B.Clergue Jul 19 '18 at 6:44
  • \$\begingroup\$ So I took away every malloc in my code (I was convinced that it is of no use in embedded systems) and now I can write in the Flash. I am still having trouble reading it, but I can see in the memory buffer that my frames are being written at the right adress. \$\endgroup\$ – B.Clergue Jul 19 '18 at 12:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.