Перейти к содержанию
    

Запись чтение в встроенную флеш память stm32 с HAL библиотекой

Привет, Всем.
Помогите разобратся с Флеш памятью (плата stm32DiscoveryF3). Использовать при этом библиотеки HAL. Материала в сети много,
но понять и пережить его не могу. Кто какие библиотеки использует, кто  на уровне регистров, в перемешку и т.д. Я как абсолютный новичок
разобраться не могу. Последите за ходом мысли и поправите.
Хочу достичь следующего результата:
-Записывать и считывать данные int32_t (знаковые).

Начал с того, что разбираюсь с структурой флеш памяти внутренней.
 1) Из User manual п.4.2 2Embedded Flash memory" узнал, что у меня 256Kbytes Flash memory
состоящей из 128 страниц по 2048 bytes каждая.

2) Свои данные (рекомендуют в статьях) собираюсь писать в последнюю страницу (у меня 12 значений int32_t соответственно
мне 12х32 = 384 bits = 48 bytes, т.е. страницы хватит).

3) Maine memory  начинается с адреса: 0x0800 0000 по 2048 bytes каждая, следовательно начальный адрес
последней страницы: 0x0800 0000 + 0х800*127 = 0х0809 3800 
(в таблице мануала даны нач. адреса до 3-ей страницы так считал все совпадало). Правильно? Хотел посмотреть на содержимое 

этой страницы с помощью  ST-LINK Utility а она мне отвечает "Can not read memory". Почему? Хотя первые страницы показывает, связь с устройством есть.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, Olegus said:

3) Maine memory  начинается с адреса: 0x0800 0000 по 2048 bytes каждая, следовательно начальный адрес
 последней страницы: 0x0800 0000 + 0х800*127 = 0х0809 3800 

Занимательная арифметика:

0x0800 0000 + 0х800*0x127 = 0х0809 3800 

0x0800 0000 + 0х800*127 = 0х0803 F800 

А в остальном всё верно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 03.04.2019 в 14:14, esaulenka сказал:

Занимательная арифметика:

0x0800 0000 + 0х800*0x127 = 0х0809 3800 

0x0800 0000 + 0х800*127 = 0х0803 F800 

А в остальном всё верно.

Спасибо, в точку. Иду дальше. 

 

 

 

Изменено пользователем Olegus

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4)  Из User manual п.4.1 узнал, что запись в память ведется через буфер словами: 2х64bit, т.е 2 буфера по 64 bit каждый?
Из Описания HAL п."HAL FLASH Generic Driver". Что пишем словами слово 32 bit (можно по два слова, полслова) :
(FLASH_TYPEPROGRAM_WORD  Program a word (32-bit) at a specified address).

 

Из Описания HAL п."HAL FLASH Generic Driver". читаю как пользоваться библиотекой функций по флеш: 19.2.2  How to use this driver.
Исходя из этого пишу следующий код(проект генерирую CubMx потому у меня HAL подключены):
 5.1)   Необходимо открыть (разблокировать) флеш для записи. ("Lock and Unlock the FLASH interface" (Из Описания HAL п."HAL FLASH Generic Driver".9.2.2  How to use this driver)) . Пишу
 

flash_ok = HAL_FLASH_Unlock();

 

5.2) Затем стереть страницу.  (Erase function: Erase page, erase all pages (Из Описания HAL п."HAL FLASH Generic Driver".9.2.2  How to use this driver). Т.е. должен стереть страницу в которую буду писать т.е. последнюю с нач. адресом)
 Для этого в соответствии с Описания HAL п.20.2.1 я должен создать структуру типа FLASH_EraseInitTypeDef

#define START_ADDR_USER_PAGE           ((uint32_t)0x0803F800)

EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;// указал что буду стирать страницу

EraseInitStruct.PageAddress = START_ADDR_USER_PAGE ;   //указываю начальный адрес стираемой страницы

EraseInitStruct.NbPages     = 0x01;// количество стираемых страниц - одна

Надеюсь пока правильно?

Изменено пользователем Olegus

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 часов назад, Olegus сказал:

Из User manual п.4.1 узнал, что запись в память ведется через буфер словами: 2х64bit

2х64bit это только при чтении кода для исполнения (prefetch buffer), а запись производится только полусловами (16 бит).

Читайте дальше :) 

Цитаты из 4.2.3 Flash program and erase operations.

"An on going Flash memory operation will not block the CPU as long as the CPU does not access the Flash memory."

В процессе записи/стирания процессор может исполнять код из ОЗУ, а если переместить таблицу векторов то и обрабатывать прерывания. Иногда, но далеко не всегда, это бывает нужно.

On the contrary, during a program/erase operation to the Flash memory, any attempt to read
the Flash memory will stall the bus. The read operation will proceed correctly once the
program/erase operation has completed.

При попытке прочитать из Flash процессор просто притормозит, а по окончании записи или стирания продолжит как ни в чем ни бывало.

После старта записи/стирания процессор может успеть исполнить несколько команд из буфера предвыборки. Этим объясняется странное требование проверять бит BSY после старта записи даже при работе программы из Flash. (4. Wait until the BSY bit is reset in the FLASH_SR register).

For program and erase operations on the Flash memory (write/erase), the internal RC oscillator (HSI) must be ON.

За этим тоже надо проследить.

Это для F3xx, у других семейств работа с Flash несколько отличается, к примеру F4xx умеет писать по 8, 16 и 32 бита за раз (и даже по 64 бита, но при весьма особых условиях с которыми мало кто готов заморачиваться).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

53 minutes ago, SSerge said:

После старта записи/стирания процессор может успеть исполнить несколько команд из буфера предвыборки. Этим объясняется странное требование проверять бит BSY

О, спасибо. Не сильно задумывался (и не проверял, что будет, если его игнорировать), но требование, действительно, на первый взгляд, избыточное.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5.3) Далее после заполнения структуры с параметрами стираемой страницы произвожу ее стирание. Использую функцию HAL_FLASHEx_Erase() (см. п.20.2.3 Описания HAL)

       

uint32_t PageError = 0x00;
       HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);

В отладчике проверил значение переменной  PageError она после вызова функции HAL_FLASHEx_Erase() стала = 0xFFFFFFFF т.е. страница стерта успешно
 (в соответствии с описанием HAL см. п.20.2.3:"PageError:  pointer to variable that contains the configuration information on faulty page
 in case of error (0xFFFFFFFF means that all the pages have been correctly erased)"
Подсмотрел через STM32 ST-Link Utility  там в каждую ячейку страницы записаны единицы. Так и должно быть (хотя я где-то читал в статьях что это исх. сост. после стирания)?
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, Olegus said:

в каждую ячейку страницы записаны единицы

Да, исходное состояние бита флеш-памяти (любой) - единичка.

На всякий случай напомню, что для NOR-памяти (используется в подавляющем большинстве контроллеров, в т.ч. и в этой ST'шке) в одну и ту же ячейку можно записывать только один раз. Потом - стирание.

Для NAND памяти ограничение ещё жёстче - единовременно надо записывать целиком страницу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, esaulenka сказал:

Да, исходное состояние бита флеш-памяти (любой) - единичка.

Может для STM это и верно, но в других МК может быть по другому.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Далее пробую записать два числа D1 и D2 to  Flash memory in STM32F303xB/C (256 Kbytes). Руководствуясь описанием HAL п.19.2.5
использую функцию  HAL_FLASH_Program(). Пишу словами по 32 бита (см.п.19.3.1. макрос: FLASH_TYPEPROGRAM_WORD - Program a word (32-bit) at a specified address.)
Размерность моих слов 32 бита = 4 ячейки памяти * 8байт, следовательно адрес второго слова смещаю на 0x4, наверно и так далее до конца стертой страницы.       

 uint32_t D1 = 0x11AEEDEE;//32 bit word
        uint32_t D2 = 0x14AEEDEE;//32 bit word

         flash_ok = HAL_ERROR;
         while(flash_ok != HAL_OK)
         {
         flash_ok = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, START_ADDR_USER_PAGE,(uint64_t)D1);
                    HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, START_ADDR_USER_PAGE + 0x4, (uint64_t)D2);
              }

Проверяю, что записал через STM32 ST-Link Utility.
Похоже что все как надо?! 

 

 

stm32 st-link Ut.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А теперь самое главное, что сразу в HAL не понял где функция чтения из памяти типа HAL_READ_....()??

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, jcxz said:

но в других МК может быть по другому.

Можно пример?

Не могу сказать, что знаю всё, но всё, что я видел (и контроллеры, и отдельные м/с памяти) по команде "стереть" выставляют 0xff.

Инвертировать внутри бит несложно (и даже иногда было б удобнее), но я ни разу с таким не сталкивался.

1 hour ago, Olegus said:

где функция чтения из памяти типа HAL_READ

Держите:

uint8_t read_byte(uint32_t addr)

{

return (volatile uint8_t *)addr;

}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 минут назад, esaulenka сказал:

Можно пример?

Семейство XMC4xxx от Infineon. После стирания все биты == 0.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

43 минуты назад, esaulenka сказал:

Можно пример?

Еще, как помню, STM8. Когда стирал STM8S003, тоже удивлялся. Хотя в datasheet на эту тему информация довольно размыта. В одном месте пишется program flash, в другом уже program eeprom... И что там реально за технология, известно только производителю. Самое интересное, что можно было бы предположить, что это все-таки EEPROM, такая же, как отведенный блок EEPROM в этом же МК. Однако у пользовательской EEPROM ресурс - сотни тысяч циклов, а в program EEPROM - всего лишь 100. Не тысяч.

А еще в каком-то STM32Lxx, не помню точно. Запускал на отладочной плате единожды, не заострил внимание на конкретной модели. Возможно на всех из серии L.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, esaulenka сказал:

Держите:


uint8_t read_byte(uint32_t addr)

{

return (volatile uint8_t *)addr;

}

Почему у меня ругается(warrning) на Вашу функцию ? 

return makes integer from pointer without a cast [-Wint-conversion] 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...