Olegus 0 3 апреля, 2019 Опубликовано 3 апреля, 2019 · Жалоба Привет, Всем. Помогите разобратся с Флеш памятью (плата 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". Почему? Хотя первые страницы показывает, связь с устройством есть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 3 апреля, 2019 Опубликовано 3 апреля, 2019 · Жалоба 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 А в остальном всё верно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Olegus 0 4 апреля, 2019 Опубликовано 4 апреля, 2019 (изменено) · Жалоба В 03.04.2019 в 14:14, esaulenka сказал: Занимательная арифметика: 0x0800 0000 + 0х800*0x127 = 0х0809 3800 0x0800 0000 + 0х800*127 = 0х0803 F800 А в остальном всё верно. Спасибо, в точку. Иду дальше. Изменено 4 апреля, 2019 пользователем Olegus Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Olegus 0 4 апреля, 2019 Опубликовано 4 апреля, 2019 (изменено) · Жалоба 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;// количество стираемых страниц - одна Надеюсь пока правильно? Изменено 4 апреля, 2019 пользователем Olegus Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 6 5 апреля, 2019 Опубликовано 5 апреля, 2019 · Жалоба 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 бита, но при весьма особых условиях с которыми мало кто готов заморачиваться). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 5 апреля, 2019 Опубликовано 5 апреля, 2019 · Жалоба 53 minutes ago, SSerge said: После старта записи/стирания процессор может успеть исполнить несколько команд из буфера предвыборки. Этим объясняется странное требование проверять бит BSY О, спасибо. Не сильно задумывался (и не проверял, что будет, если его игнорировать), но требование, действительно, на первый взгляд, избыточное. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Olegus 0 6 апреля, 2019 Опубликовано 6 апреля, 2019 · Жалоба 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 там в каждую ячейку страницы записаны единицы. Так и должно быть (хотя я где-то читал в статьях что это исх. сост. после стирания)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 6 апреля, 2019 Опубликовано 6 апреля, 2019 · Жалоба 1 hour ago, Olegus said: в каждую ячейку страницы записаны единицы Да, исходное состояние бита флеш-памяти (любой) - единичка. На всякий случай напомню, что для NOR-памяти (используется в подавляющем большинстве контроллеров, в т.ч. и в этой ST'шке) в одну и ту же ячейку можно записывать только один раз. Потом - стирание. Для NAND памяти ограничение ещё жёстче - единовременно надо записывать целиком страницу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 6 апреля, 2019 Опубликовано 6 апреля, 2019 · Жалоба 2 часа назад, esaulenka сказал: Да, исходное состояние бита флеш-памяти (любой) - единичка. Может для STM это и верно, но в других МК может быть по другому. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Olegus 0 6 апреля, 2019 Опубликовано 6 апреля, 2019 · Жалоба Далее пробую записать два числа 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. Похоже что все как надо?! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Olegus 0 6 апреля, 2019 Опубликовано 6 апреля, 2019 · Жалоба А теперь самое главное, что сразу в HAL не понял где функция чтения из памяти типа HAL_READ_....()?? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 6 апреля, 2019 Опубликовано 6 апреля, 2019 · Жалоба 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; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 6 апреля, 2019 Опубликовано 6 апреля, 2019 · Жалоба 7 минут назад, esaulenka сказал: Можно пример? Семейство XMC4xxx от Infineon. После стирания все биты == 0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 6 апреля, 2019 Опубликовано 6 апреля, 2019 · Жалоба 43 минуты назад, esaulenka сказал: Можно пример? Еще, как помню, STM8. Когда стирал STM8S003, тоже удивлялся. Хотя в datasheet на эту тему информация довольно размыта. В одном месте пишется program flash, в другом уже program eeprom... И что там реально за технология, известно только производителю. Самое интересное, что можно было бы предположить, что это все-таки EEPROM, такая же, как отведенный блок EEPROM в этом же МК. Однако у пользовательской EEPROM ресурс - сотни тысяч циклов, а в program EEPROM - всего лишь 100. Не тысяч. А еще в каком-то STM32Lxx, не помню точно. Запускал на отладочной плате единожды, не заострил внимание на конкретной модели. Возможно на всех из серии L. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Olegus 0 6 апреля, 2019 Опубликовано 6 апреля, 2019 · Жалоба 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] Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться