cancel
Showing results for 
Search instead for 
Did you mean: 

How to store data in flash memory of STM32F401CCU6?

MihirJ
Associate

My STM32F401CCU6 has 256K flash memory, and I want to use it to store some data. 

Trying to create a user kept pausing the program at the hardfault handler when I tried debugging. Where am I going wrong? Are there any good resources for this microcontroller regarding using the flash memory to store data?  

#include "user.h"
#include <string.h>
#include <stdio.h>
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_flash.h"

#define ADDR_FLASH_SECTOR_6   ((uint32_t)0x08040000)
#define FLASH_USER_START_ADDR   ADDR_FLASH_SECTOR_6
#define USER_SIZE sizeof(User)

void createUser(const char* userID, const char* password, uint8_t tier) {
    if (userExists(userID)) {
        return;
    }

    User newUser;
    strncpy(newUser.userID, userID, USER_ID_LENGTH);
    newUser.userID[USER_ID_LENGTH] = '\0';
    strncpy(newUser.password, password, PASSWORD_LENGTH);
    newUser.password[PASSWORD_LENGTH] = '\0';
    newUser.tier = tier;

    HAL_FLASH_Unlock();

    FLASH_Erase_Sector(6, VOLTAGE_RANGE_3);

    for (uint32_t address = FLASH_USER_START_ADDR; address < FLASH_USER_START_ADDR + MAX_USERS * USER_SIZE; address += USER_SIZE) {
        User tempUser;
        memcpy(&tempUser, (void *)address, USER_SIZE);
        if (strlen(tempUser.userID) == 0) {
            for (uint32_t i = 0; i < USER_SIZE; i += 4) {
                uint32_t dataToWrite = *(uint32_t *)((uint8_t *)&newUser + i);
                HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address + i, dataToWrite);
            }
            break;
        }
    }

    HAL_FLASH_Lock();
}

bool userExists(const char* userID) {
    User tempUser;
    for (uint32_t address = FLASH_USER_START_ADDR; address < FLASH_USER_START_ADDR + MAX_USERS * USER_SIZE; address += USER_SIZE) {
        memcpy(&tempUser, (void *)address, USER_SIZE);
        if (strcmp(tempUser.userID, userID) == 0) {
            return true;
        }
    }
    return false;
}

void getUserPassword(const char* userID, char* outPassword) {
    User tempUser;
    for (uint32_t address = FLASH_USER_START_ADDR; address < FLASH_USER_START_ADDR + MAX_USERS * USER_SIZE; address += USER_SIZE) {
        memcpy(&tempUser, (void *)address, USER_SIZE);
        if (strcmp(tempUser.userID, userID) == 0) {
            strncpy(outPassword, tempUser.password, PASSWORD_LENGTH + 1);
            return;
        }
    }
}

 

2 REPLIES 2

There should be FLASH examples in the CubeF4 trees for assorted boards, review those.

Check what's actually faulting, the addresses involved. Isn't 0x40000 at the 256KB limit?

Check address alignments.

Not sure how you can memcpy() from current content, and write back.

Look at the error codes from the functions, rather than ignore.

Instrument code so you can observe what's going on without the debugger stepping on everything.

You can write once to locations previously erased.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Andrew Neil
Evangelist III

You could take a look at  Application Note AN3969, EEPROM emulation in STM32F40x/STM32F41x microcontrollers

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

https://www.st.com/en/embedded-software/stsw-stm32066.html 

Even if you don't want to do the EEPROM emulation thing, it illustrates how to write to, erase, and read Flash.