STM32F4 Discovery - Запись/Чтение Flash памяти

Это мой первый пост здесь, извините, если формат или что-то не так. Мне удалось записать и прочитать флэш-память STM32F4 Discovery, следуя советам наших колледжей здесь и здесь (оба поста объясняются одинаково):

__attribute__((__section__(".user_data"))) const char userConfig[64];
[...]
void Write_Flash(uint8_t data)
{
     HAL_FLASH_Unlock();
     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR );
     FLASH_Erase_Sector(FLASH_SECTOR_6, VOLTAGE_RANGE_3);
     HAL_FLASH_Program(TYPEPROGRAM_WORD, &userConfig[0], data);
     HAL_FLASH_Lock();
}
[...]
  dataSize=(sizeof dataBuffer) / (sizeof *dataBuffer);
  for (i=0;i<dataSize;i++) {
      dataBuffer[i]=i+1;
  }
  Write_Flash(dataBuffer[0]);

Приведенный выше код работает нормально и записывает 1 в userConfig[0]. С этого момента у меня следующая проблема. Я могу записать только один байт во флэш-память и не знаю, как записать больше. Я пытался изменить адрес HAL_FLASH_Program(TYPEPROGRAM_WORD, &userConfig[0], data);, но работает только для &userConfig[0] Это моя попытка написать несколько байтов без успеха:

__attribute__((__section__(".user_data"))) const char userConfig[64];
[...]
void Write_Flash(uint8_t data, uint8_t i)
    {
         HAL_FLASH_Unlock();
         __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR );
         FLASH_Erase_Sector(FLASH_SECTOR_6, VOLTAGE_RANGE_3);
         HAL_FLASH_Program(TYPEPROGRAM_WORD, &userConfig[i], data);
         HAL_FLASH_Lock();
    }
[...]
dataSize=(sizeof dataBuffer) / (sizeof *dataBuffer);
for (i=0;i<dataSize;i++) {
      dataBuffer[i]=i+1;
      Write_Flash(dataBuffer[i],i);
  }

Заранее спасибо за вашу помощь.


person Manuel Illueca    schedule 11.03.2018    source источник
comment
Насколько мне известно, у устройств флэш-памяти NAND есть некоторые ограничения на размер отдельных операций записи. Флэш-память должна быть записана в виде сектора, а не байта (это не байтовая адресация). Итак, я рекомендую вам попробовать записать более 1 байта и посмотреть, получится ли у вас.   -  person campescassiano    schedule 11.03.2018
comment


Ответы (1)


Благодаря @phyloflash я получил ответ. При вызове HAL_FLASH_Program вы указываете размер записываемых данных и адрес первого байта этих данных. В моем случае HAL_FLASH_Program(TYPEPROGRAM_WORD, &userConfig[0], data); слово означает 4 байта, поэтому были записаны первые 4 байта userConfig. Это также означает, что параметр, определенный как uint8_t data, должен соответствовать размеру данных, которые вы собираетесь записать, поэтому он должен быть uint32_t data.

Я изменил код, чтобы учесть эти соображения. Код ниже проверен и работает:

//data type have to be consistent with the TYPEPROGRAM, i.e:
//TYPEPROGRAM_BYTE uint8_t data
//TYPEPROGRAM_HALFWORD uint16_t data
//TYPEPROGRAM_WORD uint32_t data
//TYPEPROGRAM_DOUBLEWORD uint64_t data
void Write_Flash(uint32_t data[],uint8_t flashTypeProgram)

{
     uint8_t addressGap;
     HAL_FLASH_Unlock();
     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR );
     FLASH_Erase_Sector(FLASH_SECTOR_6, VOLTAGE_RANGE_3);
     for (i=0;i<64/pow(2, flashTypeProgram);i++)
     {
         addressGap=pow(2, flashTypeProgram)*i;
         HAL_FLASH_Program(flashTypeProgram, &userConfig[0]+addressGap, data[i]);
     }
     HAL_FLASH_Lock();
     //TYPEPROGRAM_BYTE        Program byte (8-bit) at a specified address              $0
     //TYPEPROGRAM_HALFWORD    Program a half-word (16-bit) at a specified address      $1
     //TYPEPROGRAM_WORD        Program a word (32-bit) at a specified address           $2
     //TYPEPROGRAM_DOUBLEWORD  Program a double word (64-bit) at a specified address    $3
}
[...]
  flashTypeProgram=TYPEPROGRAM_WORD;
  dataSize=(sizeof dataBuffer) / (sizeof *dataBuffer);
  for (i=0;i<dataSize;i++) {
      dataBuffer[i]=0x1010101;  //0x1010101 puts 1 in each byte of userConfig
  }
  Write_Flash(dataBuffer,flashTypeProgram);
person Manuel Illueca    schedule 11.03.2018