cancel
Showing results for 
Search instead for 
Did you mean: 

Use STM32F4 flash for non-volatile data storage (eeprom)

syedhashmiraza
Associate II

hello i am using stm32f429i-disc1 microcontroller board in this how to generate flash code (eeprom)

 


Your other thread showed a major confusion between what is a "microcontroller", and what is a "board" - so edited for clarity.

29 REPLIES 29

@syedhashmiraza wrote:

this code is not build in stm32cubeide


how did you download from GitHub?

It's important to use git clone --recursive - the Zip download won't work:

https://community.st.com/t5/stm32-mcus/downloading-stm32cube-packages-from-github-correctly/ta-p/725288

 

Hello @syedhashmiraza 

Please don't duplicate the same subject on multiple threads. 

This thread will be merged with the previous one.

Thank you for your understanding.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

@syedhashmiraza wrote:

this is my code but in this code string is not storing in eeprom


So you got it to build? Well done!

How do you determine that the string is not being stored?

Is it storing anything at all ?

Did you run the demo? Did that work?

Did you study the Application Note, which describes what this code does, and how to use it?

AndrewNeil_0-1731928988327.png

https://www.st.com/resource/en/application_note/an3969-eeprom-emulation-in-stm32f40xstm32f41x-microcontrollers-stmicroelectronics.pdf#page=13

As that description says, the EE_WriteVariable() function updates a Virtual Variable in the emulated EEPROM.

See also the documentation in the source code itself:

/**
* @brief Writes/updates variable data in EEPROM.
* @param VirtAddress: Variable virtual address
* @param Data: 16 bit data to be written
* @retval Success or error status:
* - FLASH_COMPLETE: on success
* - PAGE_FULL: if valid page is full
* - NO_VALID_PAGE: if no valid page was found
* - Flash error code: on write Flash error
*/

So that's writing 16-bit data - or two characters at once.

You will need something like:

 

char writeString[] = "Hello";
int string_idx = 0;  // Index to characters in the string
int eeprom_idx;      // Index to Virtual Variables in the emulated EEPROM
for( eeprom_idx = 0; i < strlen(writeString)/2; eeprom_idx++ )
{
   if( EE_WriteVariable( VirtAddVarTab[0] + eeprom_idx, (uint16_t*)&writeString[string_idx ]) != HAL_OK)
   {
      Error_Handler();
   }
   string_idx += 2;
}

 

 

In general, you will have to also cope with

  1. Odd number of characters in the string
  2. Having enough Virtual Variables for the length of the string.

In both cases, you are lucky so far that this happens to be OK.

 

As I said initially:

"It may not exactly suit your requirements, but it does show how to use the STM32F4 Flash for data storage."

It certainly isn't great for saving strings ...

hello in this code not storing string after power cut and poer on in eeprom not storing and in this code how to use printf?

/* Includes ------------------------------------------------------------------*/

#include "main.h"

#include <stdio.h>

/** @addtogroup EEPROM_Emulation

* @{

*/



/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/



/* Virtual address defined by the user: 0xFFFF value is prohibited */

uint16_t VirtAddVarTab[NB_OF_VAR] = {0x5555, 0x6666, 0x7777};

uint16_t VarDataTab[NB_OF_VAR] = {0, 0, 0};

uint16_t VarValue,VarDataTmp = 0;

/* Private function prototypes -----------------------------------------------*/

static void SystemClock_Config(void);

static void Error_Handler(void);



/* Private functions ---------------------------------------------------------*/



/**

* @brief Main program.

* @PAram None

* @retval None

*/



//char writeString[] = "Hello Hashmi";

char readString[64]={0};





int main(void)

{

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();



/* Configure the system clock to 180 MHz */

SystemClock_Config();



/* Unlock the Flash Program Erase controller */

HAL_FLASH_Unlock();



/* Configure LED3 */

BSP_LED_Init(LED3);



/* EEPROM Init */

if( EE_Init() != EE_OK)

{

Error_Handler();

}



if (EE_ReadVariable(VirtAddVarTab[0], &VarDataTmp) != HAL_OK)

{

Error_Handler();

}

char writeString[] = "Hello";

for (int i = 0; i < sizeof(writeString); i++)

{

uint16_t charToWrite = (uint16_t)writeString[i];



// Pass the value, not the pointer

if (EE_WriteVariable(VirtAddVarTab[0] + i, charToWrite) != HAL_OK)

{

Error_Handler();

}



}





//printf("hello");









}





static void SystemClock_Config(void)

{

RCC_ClkInitTypeDef RCC_ClkInitStruct;

RCC_OscInitTypeDef RCC_OscInitStruct;

HAL_StatusTypeDef ret = HAL_OK;



/* Enable Power Control clock */

__HAL_RCC_PWR_CLK_ENABLE();



/* The voltage scaling allows optimizing the power consumption when the device is

clocked below the maximum system frequency, to update the voltage scaling value

regarding system frequency refer to product datasheet. */

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);



/* Enable HSE Oscillator and activate PLL with HSE as source */

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLM = 8;

RCC_OscInitStruct.PLL.PLLN = 360;

RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

RCC_OscInitStruct.PLL.PLLQ = 7;

HAL_RCC_OscConfig(&RCC_OscInitStruct);

ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);



if(ret != HAL_OK)

{

while(1) { ; }

}



/* Activate the Over-Drive mode */

HAL_PWREx_EnableOverDrive();



/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2

clocks dividers */

RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);

if(ret != HAL_OK)

{

while(1) { ; }

}

}



/**

* @brief This function is executed in case of error occurrence.

* @PAram None

* @retval None

*/

static void Error_Handler(void)

{

while(1)

{

/* Toggle LED3 fast */

BSP_LED_Toggle(LED3);

HAL_Delay(40);

}

}



#ifdef USE_FULL_ASSERT



/**

* @brief Reports the name of the source file and the source line number

* where the assert_param error has occurred.

* @PAram file: pointer to the source file name

* @PAram line: assert_param error line source number

* @retval None

*/

void assert_failed(uint8_t* file, uint32_t line)

{

/* User can add his own implementation to report the file name and line number,

ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */



/* Infinite loop */

while (1)

{

}

}

#endif



/**

* @}

*/



 

syedhashmiraza
Associate II

Again, please stop creating multiple threads on the same topic. Merged into original Thread.


 

hello in this code not storing string after power cut and poer on in eeprom not storing and in this code how to use printf?

 

 

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include <stdio.h>

/** @addtogroup EEPROM_Emulation
* @{
*/

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/

/* Virtual address defined by the user: 0xFFFF value is prohibited */
uint16_t VirtAddVarTab[NB_OF_VAR] = {0x5555, 0x6666, 0x7777};
uint16_t VarDataTab[NB_OF_VAR] = {0, 0, 0};

uint16_t VarValue,VarDataTmp = 0;

/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
static void Error_Handler(void);

/* Private functions ---------------------------------------------------------*/

/**
* @brief Main program.
*  None
* @retval None
*/

//char writeString[] = "Hello Hashmi";
char readString[64]={0};

int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* Configure the system clock to 180 MHz */
SystemClock_Config();

/* Unlock the Flash Program Erase controller */
HAL_FLASH_Unlock();

/* Configure LED3 */
BSP_LED_Init(LED3);

/* EEPROM Init */
if( EE_Init() != EE_OK)
{
Error_Handler();
}

if (EE_ReadVariable(VirtAddVarTab[0], &VarDataTmp) != HAL_OK)
{
Error_Handler();
}

char writeString[] = "Hello";
for (int i = 0; i < sizeof(writeString); i++)
{
uint16_t charToWrite = (uint16_t)writeString[i];

// Pass the value, not the pointer
if (EE_WriteVariable(VirtAddVarTab[0] + i, charToWrite) != HAL_OK)
{
Error_Handler();
}
}

//printf("hello");
}

static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
HAL_StatusTypeDef ret = HAL_OK;

/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();

/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 360;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
if(ret != HAL_OK)
{
while(1) { ; }
}

/* Activate the Over-Drive mode */
HAL_PWREx_EnableOverDrive();

/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
if(ret != HAL_OK)
{
while(1) { ; }
}
}

/**
* @brief This function is executed in case of error occurrence.
*  None
* @retval None
*/
static void Error_Handler(void)
{
while(1)
{

/* Toggle LED3 fast */
BSP_LED_Toggle(LED3);
HAL_Delay(40);
}
}

#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
*  file: pointer to the source file name
*  line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

/* Infinite loop */
while (1)
{
}
}
#endif

/**
* @}
*/

 

Hello @syedhashmiraza ,

Please review tips on posting a thread in this community, especially for the following points:

- Title: "store" does not mean anything in the title needs to be short (not tooo short) and concise.

- Posting a code: you need to use </> button to paste your code.

- Part number: always state the FULL Part Number of the product used.

+

1- "hello in this code not storing string after power cut and poer on in eeprom not storing and in this code how to use printf?" -> not clear what do you mean by that. Need to elaborate more.

2- The thread subject is not related to CubeIDE usage but to the product usage -> To be moved to STM32 MCUs Products forum board.

Thank you for your understanding.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

@syedhashmiraza wrote:

hello in this code not storing string after power cut and poer on in eeprom not storing and in this code 


That code seems to be unchanged from your earlier post:

https://community.st.com/t5/stm32-mcus-products/use-stm32f4-flash-for-non-volatile-data-storage-eeprom/m-p/743983/highlight/true#M266531

I asked you questions about that, and pointed out some issues here:

https://community.st.com/t5/stm32-mcus-products/use-stm32f4-flash-for-non-volatile-data-storage-eeprom/m-p/744136/highlight/true#M266554

 


@syedhashmiraza wrote:

how to use printf?


That's an entirely separate question.

  1. First, you need to get basic, direct UART output working:
    https://wiki.st.com/stm32mcu/wiki/Getting_started_with_UART

  2. Then - and only then - you can redirect printf to your working UART output:
    https://community.st.com/t5/stm32-mcus/how-to-redirect-the-printf-function-to-a-uart-for-debug-messages/ta-p/49865 

https://community.st.com/t5/stm32-mcus-embedded-software/how-to-redirect-the-printf-function-to-a-uart-for-debug-messages/m-p/740284/highlight/true#M56711

Of course, having got the basic UART output working, you may find that you don't really need printf ...

If you have further questions about that, it is a separate question - so do start a new thread for it.

@syedhashmiraza 

Again, please use </> button to share your code.

Thanks

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
SofLit
ST Employee

You posted again the same question in a new thread which I moved to the forum archive.

Please don't duplicate threads! and keep the discussion in the same conversation until you solve your issue or you have another question.

Any further duplication will be moved to the archive.

Thank you for your understanding.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.