c - эмуляция EEPROM STM32F1 через флэш - PullRequest
0 голосов
/ 02 июля 2018

Я пытаюсь эмулировать EEPROM через флэш-память на моем STM32F1, как описано, например, здесь (для STM32F4), но я пытаюсь изменить код для спецификаций STM32F1RB (средней плотности). Я использую SW4STM32, CubeMX и HAL API.

__attribute__((__section__(".user_data"))) const char userConfig[64];

//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);

Я изучил способ записи данных во флэш-память с помощью HAL API, но, поскольку я не хочу «испортить» свою плату из-за неправильной части памяти, я хочу убедиться, что я все понимаю, прежде чем пытаться мой собственный.

Прежде всего, скажем, я хочу, чтобы 5 Кбайт данных были сохранены. Как мне разрешить зону данных? начиная с конца основной зоны памяти? Например, я мог бы назначить страницы 127 - 122 для моих данных? как это?

MEMORY
 {
   DATA (RWX)      : ORIGIN = 0x08048800, LENGTH = 5k      /* 0x08048000 is the beginning of page 107 */
   ...
}

что было бы неплохо разрешить 5 страниц для флэш-памяти?

Далее я не совсем понимаю эту строку:

__attribute__((__section__(".user_data"))) const char userConfig[64];

Я понял, что пользователь может читать данные, хранящиеся во Flash, но почему он назначен таким образом? Я имею в виду, 64 * sizeof (char) = 64 байта, верно? Как он назначает только 64 байта для чтения, в то время как он разрешил 128 кБ памяти?

Заранее спасибо!

1 Ответ

0 голосов
/ 02 июля 2018

Во-первых, вы должны сказать, что пытаетесь что-то записать в Data Flash. Основное отличие состоит в том, что вы должны стереть всю страницу, чтобы что-то написать. Во время копирования данных в EEPROM такого ограничения нет.

Я вижу, что вы используете только библиотеку HAL из чьих-либо других источников, и я полагаю, что вы не имеете полного контроля над тем, что именно вы делаете. Пожалуйста, обратитесь к Руководству по программированию флэш-памяти для STM32F1xx. Есть письменные инструкции о том, что именно вы должны делать и какие регистры важны при программировании флэш-памяти.

Не бойся, ты ничего не уничтожишь.

Пожалуйста, не изменяйте раздел ниже. Это только означает, где начинается Flash и сколько там байтов. Вас должен интересовать только код, который будет изменять содержимое Flash (ваш код, который вы напишите).

MEMORY
{
   DATA (RWX)      : ORIGIN = 0x08048800, LENGTH = 5k      /* 0x08048000 is the beginning of page 107 *

Передо мной нет HAL API, но я полагаю, что для адреса, по которому записываются данные, требуется целое число.

Во-первых, пожалуйста, уменьшите ваш код до минимальной формы. Выйдите из цикла и попробуйте запрограммировать только половину слова (2 байта) - программирование в этом ЦП выполняется на половине слова, поэтому ваш адрес должен быть выровнен до двух.

Ниже строки просто объявление некоторой памяти. Вам не нужно это для программирования Data Flash.

 __attribute__((__section__(".user_data"))) const char userConfig[64];

Вы смотрели в руководство, которое я вам порекомендовал?

...