crashstm32eraseflash-memory

STM32 Crash on Flash Sector Erase


I'm trying to write 4 uint32's of data into the flash memory of my STM32F767ZI so I've looked at some examples and in the reference manual but still I cannot do it. My goal is to write 4 uint32's into the flash and read them back and compare with the original data, and light different leds depending on the success of the comparison. My code is as follows:

void flash_write(uint32_t offset, uint32_t *data, uint32_t size) {
    FLASH_EraseInitTypeDef EraseInitStruct = {0};
    uint32_t SectorError = 0;

    HAL_FLASH_Unlock();

    EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
    EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
    EraseInitStruct.Sector = FLASH_SECTOR_11; 
    EraseInitStruct.NbSectors = 1;
    //EraseInitStruct.Banks = FLASH_BANK_1; // or FLASH_BANK_2 or FLASH_BANK_BOTH

    st = HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);

    if (st == HAL_OK) {
        for (int i = 0; i < size; i += 4) {
            st = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FLASH_USER_START_ADDR + offset + i, *(data + i)); //This is what's giving me trouble
            if (st != HAL_OK) {
                // handle the error
                break;
            }
        }
    }else {
        // handle the error
    }
    HAL_FLASH_Lock();
}

void flash_read(uint32_t offset, uint32_t *data, uint32_t size) {
    for (int i = 0; i < size; i += 4) {
        *(data + i) = *(__IO uint32_t*)(FLASH_USER_START_ADDR + offset + i);
    }
}

int main(void) {

    uint32_t data[] = {'a', 'b', 'c', 'd'};
    uint32_t read_data[] = {0, 0, 0, 0};

    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();

    flash_write(0, data, sizeof(data));
    flash_read(0, read_data, sizeof(read_data));

    if (compareArrays(data,read_data,4))
    {
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7,SET);
    }
    else
    {
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14,SET);
    }

    return 0;
}

The problem is that before writing data I must erase a sector, and when I do it with the HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError), function, the program always crashes, and sometimes even corrupts my codespace forcing me to update firmware. I've selected the sector farthest from the code space but still it crashes when i try to erase it. I've read in the reference manual that

Any attempt to read the Flash memory while it is being written or erased, causes the bus to stall. Read operations are processed correctly once the program operation has completed. This means that code or data fetches cannot be performed while a write/erase operation is ongoing.

which I believe means the code should ideally be run from RAM while we operate on the flash, but I've seen other people online not have this issue so I'm wondering if that's the only problem I have. With that in mind I wanted to confirm if this is my only issue, or if I'm doing something wrong?


Solution

  • In your loop, you are adding multiples of 4 to i, but then you are adding i to data. When you add to a pointer it is automatically multiplied by the size of the pointed type, so you are adding multiples of 16 bytes and reading past the end of your input buffer.

    Also, make sure you initialize all members of EraseInitStruct. Uncomment that line and set the correct value!