|
Эмуляция EEPROM в первых двух секторах STM32F4, Старт программы с предопределённого адреса |
|
|
|
Oct 7 2014, 06:41
|
Знающий
   
Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231

|
Цитата(AlexUT4 @ Aug 28 2013, 22:40)  Большое спасибо за наводку.... сделал по такому примеру, всё работает, но есть следующий вопрос: При такой записи регион с дырой получается, но есть одно НО, вектора прерываний разместятся с адреса 0x08000000, а код весь будет размещён после выделенных регионом под EEPROM. Т.е. такой записи (где используются сектора 1 и 2) код разместится с адреса 0x0800c000, а если назначить для эмуляции EEPROM сектора 2 и 3, то код разместится уже по адресу 0x08010000. Т.о. получается, если делать дыру во флеши для EEPROM надо использовать всегда сектора начиная с 1-го иначе будет потеря секторов флеши. И также 0 сектор тоже практически будет потерян по памяти, т.к. в нём кроме таблицы прерываний ничего не размещается (т.е. для эмуляции EEPROM будут потеряны 3 сектора, 2 сектора на EEPROM, а один будет гулять практически пустым). Можно ли это как то обойти, может ещё нужно в линкере чего-то прописывать? Прибивать ф-ции или массивы констант по конкретным адресам желания нет. В данном проект памяти хватает и потеря 3-х секторов по 16К не критична, но на будущее хочется уметь использовать всю память
Сообщение отредактировал IgorKossak - Oct 7 2014, 14:11
Причина редактирования: избыточное цитирование
|
|
|
|
|
Oct 7 2014, 09:48
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(Сергей Борщ @ Oct 7 2014, 13:34)  А в целом я бы отдал нулевой сектор загрузчику и забыл про него, а программу размещал бы целым куском уже после секторов эмуляции ЭСППЗУ. +1. Собственно, с такой картой распределения секторов ничего лучше и не придумаешь. Код MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K BKPSRAM(rw!x): ORIGIN = 0x40024000, LENGTH = 4K BOOTLOADER (rx) : ORIGIN = 0x08000000, LENGTH = 16K EEPROM (rw!x) : ORIGIN = 0x08004000, LENGTH = 16K + 16K IMAGE (rw!x) : ORIGIN = 0x0800C000, LENGTH = 16K + 64K FLASH (rwx) : ORIGIN = 0x08020000, LENGTH = 128K }
|
|
|
|
|
Oct 7 2014, 10:14
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(Rash @ Oct 7 2014, 10:41)  Можно ли это как то обойти, может ещё нужно в линкере чего-то прописывать? Прибивать ф-ции или массивы констант по конкретным адресам желания нет. ИМХО, такой фичи нет. Цитата(Rash @ Oct 7 2014, 10:41)  В данном проект памяти хватает и потеря 3-х секторов по 16К не критична, но на будущее хочется уметь использовать всю память Ну так и не надо дёргаться раньше времени. Страшный день, когда кончится память, скорее всего никогда не наступит. Кроме того, как известно, "преждевременная оптимизация - корень всех зол". А если когда-нибудь действительно припрёт, то ручками разложить секции не так уж и сложно.
|
|
|
|
|
Oct 8 2014, 14:17
|
Знающий
   
Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231

|
не много не по секторам, но про эмуляцию. Модернизировал то, что написано STM, добавил возможность писать не только 16, но и 8 и 32 битные данные (выбирается через дефайн). И запустил их тестовый проект. Так вот, при записи 16 битных и 32 битных данных, проблем нет, а при записи 8-ми битных данных при переходе с одной страницы на другую страницу, заполненная страница не всегда полностью очищается, что приводит к дальнейшему неверному чтению данных. Это происходит в ф-ции EE_PageTransfer(...) , где страница очищается ф-цией Код flash_status = FLASH_EraseSector(old_page_Id, VOLTAGE_RANGE); Если ставить точки останова в ф-ции EE_PageTransfer(...), не важно в каких местах, то такой проблемы нет. Другой вариант решения этой проблемы добавлением инструкции __DSB() или задержки (хватило где-то 35 NOPов) Код static uint16_t EE_PageTransfer(uint32_t v_addr, uint32_t data) { ... flash_status = FLASH_EraseSector(old_page_Id, VOLTAGE_RANGE); __DSB(); ... } либо отредактировать FLASH_EraseSector() в конце дописать __DSB(), на всякий случай
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|