Hola a todos,
Estoy intentando escribir en el FLASH de mi STM32F1, pero por alguna razón no funciona ... Siempre que estoy programando algo, devolverá un error: HAL_FLASH_ERROR_PROG, que es un error de programación. Cuando lo veo en el registro de estado de flash, significa: configurado por hardware cuando una dirección a programar contiene un valor diferente de '0xFFFF' antes de la programación.
Cuando luego analizo en la memoria FLASH de mi STM32F1, veo que el rangin de memoria de: 0x801EC00 a 0x801F17F se llena con 0x0000. De ahí el error de programación.
Lo que no entiendo es por qué no se ha borrado esta parte de la memoria. Aquí está mi código:
/* 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
para el script del enlazador
#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;
}
La función "Saving_Flash" es la que llamo en main.c para guardar los mensajes CAN_Tab_Tx en el FLASH. Se supone que Flash_writepreparation () prepara el Flash para ser escrito (desbloquea, borra las 5 páginas, borra las banderas). Finalmente, Flash_CANTx_write escribe cada fotograma de la matriz en el FLASH.
Si tiene alguna idea de por qué HAL_FLASHEx_Erase () no funciona ...
Solo para agregar: no hay ninguna advertencia o error especial cuando compilo mi código.
¡Gracias de antemano!
He intentado cambiar la dirección de HAL_FLASH_Program en FLASH_CANTx_Write, para poner & CAN_Tab_RxMessages_Flash, ahora, desde 0x801F180 a 0x801F888 en el búfer de memoria es igual a 00000000. Así que parece que depende de donde quiero escribir la dirección no se borrará correctamente ... Pero no sé cómo tratar con ella ...
EDITAR: está funcionando! más o menos ... La escritura ahora funciona, pero la lectura no es completamente ...
Para recuperar los datos que escribí en Flash, estoy haciendo esto:
__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];
}
Dado que el número de Tx Frames se almacena en el byte derecho de number_Frames_Flash, solo miro el byte derecho. Pero el problema es que CAN_nb_frames_Tx permanece = 0; mientras que si observo el valor de "(number_Frames_Flash & 0x000000FF)" en el depurador, es igual al valor que espero (es decir, el número de Tx Frames). No sé de dónde viene ...
Ya casi termino!