Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F: Функция в RAM
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
amiller
Раньше я много работал с серией микроконтроллеров C2000 от Техаса.
Там был механизм (CCStudio), позволяющий разместить любую функцию в RAM. Это позволяло существенно ускорить выполнение критического кода, а также избежать остановки выполнения программы в процессе записи или стирания Flash. Механизм примерно такой:
1. Для информирования линкера создавалась специальная секция: размещение во Flash, запуск из RAM.
2. При компоновке линкер все адреса вызовов модифицирует так, как будто этот код уже располагается в RAM.
3. В процессе инициализации эта секция копируется в RAM стандартно, по аналогии с инициализируемыми переменными.
4. При выполнении, при обращении к функции происходит переход по адресу в RAM.
К сожалению для STM32 я пока не обнаружил аналогичного механизма.
Больше всего меня смущает не быстродействие (конвейер в STM32 достаточно хорош), а проблема, связанная со стиранием больших секторов. Например в STM32F4 время, на которое код зависает при выполнении из Flash, может достигать сотен миллисекунд.
Конечно можно весь код разместить в RAM, но не всегда это возможно из соображений размера, да и защита от несанкционированного копирования кода в этом случае имеет проблемы.
Хотелось бы более красивое решение.
Есть мысли по этому поводу? Может я просто не нашёл нужный документ или пример?
DmitryM
Цитата(amiller @ Apr 21 2016, 11:46) *


для gcc: __attribute__ ((section(".ramfunc")))
jcxz
Цитата(amiller @ Apr 21 2016, 13:46) *
К сожалению для STM32 я пока не обнаружил аналогичного механизма.

Обнаруживать Вам надо не в STM, а в компиляторе. Какой компилятор?

Цитата(amiller @ Apr 21 2016, 13:46) *
Есть мысли по этому поводу? Может я просто не нашёл нужный документ или пример?

Использовать EEPROM (если таковая есть в Вашем МК) или внешнюю FLASH.
amiller
Да этот важный момент я упустил. среда программирования - IAR.
IV_K
Цитата(amiller @ Apr 21 2016, 11:14) *
Да этот важный момент я упустил. среда программирования - IAR.


__ramfunc
https://www.iar.com/support/tech-notes/link...ewarm-5.x--6.x/
scifi
Цитата(amiller @ Apr 21 2016, 10:46) *
Больше всего меня смущает не быстродействие (конвейер в STM32 достаточно хорош), а проблема, связанная со стиранием больших секторов. Например в STM32F4 время, на которое код зависает при выполнении из Flash, может достигать сотен миллисекунд.

Зависит от того, что вы хотите делать в течение этих сотен миллисекунд. Если что-то нетривиальное, то обнаружите, что половину вашего кода, если не больше, нужно будет размещать в ОЗУ. Причём отделить нужное от ненужного будет ой как не просто.
Кстати, зачем стираете большие сектора? Я для эмуляции EEPROM выделяю 2 сектора по 16 кБайт. Там типичное время стирания сектора 250 мс. В моих применениях программа может подождать 250 мс.
SSerge
Цитата(amiller @ Apr 21 2016, 15:14) *
Да этот важный момент я упустил. среда программирования - IAR.

Значит Вам повезло, потому что в папке doc есть файл EWARM_DevelopmentGuide.ENU.pdf.
Там есть описание как работает __ramfunc и какие изменения нужно сделать в конфиге линкера (initialize by copy { section .textrw }; ).
amiller
Цитата(scifi @ Apr 21 2016, 12:04) *
Зависит от того, что вы хотите делать в течение этих сотен миллисекунд. Если что-то нетривиальное, то обнаружите, что половину вашего кода, если не больше, нужно будет размещать в ОЗУ. Причём отделить нужное от ненужного будет ой как не просто.
Кстати, зачем стираете большие сектора? Я для эмуляции EEPROM выделяю 2 сектора по 16 кБайт. Там типичное время стирания сектора 250 мс. В моих применениях программа может подождать 250 мс.

У меня примерно так: Первые два сектора по 16к - загрузчик. Следующие два сектора по 16к - EEPROM. Затем код основной программы. В конце два больших сектора под запись протоколов.
Устройство должно протоколировать все события в системе. Протоколы пишутся во кругу в два сектора. И всё равно когда то наступает момент, когда нужно стереть сектор. Я конечно стараюсь отложить этот момент на время, безопасное со всех точек зрения, но проблема существует.
По поводу того, что именно помещать в ОЗУ, да такая проблема есть, но решаемая. Обычно это прерывания, плюс несколько важных функций.
В нормальном режиме у устройства обмен по нескольким каналам связи со скоростями 5-10кбайт в секунду. Зависание на такое время (сотни миллисекунд) даже визуально проявляется на мониторе связи. Не говоря уже о таких процессах, как управление ШИМ-преобразователем.
Кстати ещё один вопрос: Если во время стирания флэш, произойдёт любое обращение к флэш, то программа зависнет до окончания операции стирания? Или обработка прерывания возможна? Скорее всего, даже для того, чтобы работали прерывания, нужно на время операции стирания исключить любые обращения к флэш. Так?


Цитата(SSerge @ Apr 21 2016, 12:15) *
Значит Вам повезло, потому что в папке doc есть файл EWARM_DevelopmentGuide.ENU.pdf.
Там есть описание как работает __ramfunc и какие изменения нужно сделать в конфиге линкера (initialize by copy { section .textrw }; ).

Спасибо, посмотрю. Наверное это то, что мне нужно. Хотя документ известный, вряд ли я мимо прошёл. Может чем то не устроил.
jcxz
Цитата(amiller @ Apr 21 2016, 16:03) *
Устройство должно протоколировать все события в системе. Протоколы пишутся во кругу в два сектора. И всё равно когда то наступает момент, когда нужно стереть сектор. Я конечно стараюсь отложить этот момент на время, безопасное со всех точек зрения, но проблема существует.

Как я уже писал - копеечная SPI (или I2C) FLASH спасёт отца русской демократии laughing.gif
Либо выберите другой МК, где есть встроенная EEPROM (или даже FRAM).
А ещё можно вообще не писать во FLASH, а накапливать в ОЗУ. Сделать монитор питания и по сбою питания быстро скидывать в FLASH (предварительно стёртую).
scifi
Цитата(amiller @ Apr 21 2016, 13:03) *
Кстати ещё один вопрос: Если во время стирания флэш, произойдёт любое обращение к флэш, то программа зависнет до окончания операции стирания?

Да.

Цитата(amiller @ Apr 21 2016, 13:03) *
Или обработка прерывания возможна?

Нет.

Цитата(amiller @ Apr 21 2016, 13:03) *
Скорее всего, даже для того, чтобы работали прерывания, нужно на время операции стирания исключить любые обращения к флэш. Так?

Да.

Кстати, в том же STM32F427 есть такая штука, как два банка флеш. Пока один банк стирается, программа может выполняться из другого.
Или поставьте внешнюю флешку SOIC8 из 25-й серии. Их везде как грязи, и стоят они копейки.
SSerge
Цитата(amiller @ Apr 21 2016, 17:03) *
Кстати ещё один вопрос: Если во время стирания флэш, произойдёт любое обращение к флэш, то программа зависнет до окончания операции стирания? Или обработка прерывания возможна? Скорее всего, даже для того, чтобы работали прерывания, нужно на время операции стирания исключить любые обращения к флэш. Так?

Именно.
Цитата
Any attempt to read the Flash memory on STM32F4xx while it is being written or erased,
causes the bus to stall. Read operations are processed correctly once the program
operation has completed. This means that code or data fetches cannot be performed while
a write/erase operation is ongoing.

Т.е. читать можно, но это приведёт к приостановке выполнения программы до конца операции стирания или записи.
Именно это и происходит при обычном стирании/записи без перемещения программы в RAM.
Цитата
On STM32F42xxx and STM32F43xxx devices, two banks are available allowing read
operation from one bank while a write/erase operation is performed to the other bank.

А на этих контроллерах можно исполнять программу из одного банка в то время как второй пишется или стирается.
amiller
Цитата(scifi @ Apr 21 2016, 13:15) *
Кстати, в том же STM32F427 есть такая штука, как два банка флеш. Пока один банк стирается, программа может выполняться из другого.
Или поставьте внешнюю флешку SOIC8 из 25-й серии. Их везде как грязи, и стоят они копейки.

Про два банка я в курсе. Но обычно при выборе контроллера масса разных критериев и удобство записи во flash не является определяющим.
Внешняя флешка, возможно это и правильно, но какой то не наш способ. Вроде потому, что не смог реализовать нормальный функционал на основной памяти контроллера.
Ведь многие применяют эмуляцию EEPROM, хотя внешняя микросхема EEPROM тоже стоит копейки.
Кстати я столкнулся с тем, что при наличии мощного источника помех, например вакуумный выключатель рядом, запись во внешнюю память (использовал SPI-FRAM) сопровождается сбоями.
Я рассчитывал, что запись внутри контроллера будет надежнее в этом плане.
scifi
Цитата(amiller @ Apr 21 2016, 13:56) *
Внешняя флешка, возможно это и правильно, но какой то не наш способ. Вроде потому, что не смог реализовать нормальный функционал на основной памяти контроллера.

Я тоже так думал, когда был моложе biggrin.gif
Сложность разработки - не пустой звук. Цените своё время и труд. Плюс чем сложнее функционал, тем тяжелее его отладить и отловить все глюки, то есть надёжность легко может пострадать.

Цитата(amiller @ Apr 21 2016, 13:56) *
Ведь многие применяют эмуляцию EEPROM, хотя внешняя микросхема EEPROM тоже стоит копейки.

Внешняя EEPROM не отменяет необходимость проверять целостность данных, а примерно половина функционала эмуляции EEPROM именно этим и занимается.

Цитата(amiller @ Apr 21 2016, 13:56) *
Кстати я столкнулся с тем, что при наличии мощного источника помех, например вакуумный выключатель рядом, запись во внешнюю память (использовал SPI-FRAM) сопровождается сбоями.

Тут можно поставить фильтры (RC) и соответственно снизить скорость обмена.
jcxz
Цитата(amiller @ Apr 21 2016, 16:56) *
Кстати я столкнулся с тем, что при наличии мощного источника помех, например вакуумный выключатель рядом, запись во внешнюю память (использовал SPI-FRAM) сопровождается сбоями.

Пинайте ваших схемотехников - пусть руки выпрямляют.
Наши счётчики э-энергии работают на подстанциях без проблем. А у них и SPI-FLASH и SPI-FRAM есть. И пишут туда в непрерывном режиме.

Цитата(scifi @ Apr 21 2016, 17:04) *
Тут можно поставить фильтры (RC) и соответственно снизить скорость обмена.

Проблема не в скорости, а в грамотной разводке платы.
amiller
Цитата(jcxz @ Apr 21 2016, 14:42) *
Пинайте ваших схемотехников - пусть руки выпрямляют.
Наши счётчики э-энергии работают на подстанциях без проблем. А у них и SPI-FLASH и SPI-FRAM есть. И пишут туда в непрерывном режиме.
Проблема не в скорости, а в грамотной разводке платы.

Есть небольшая проблема: Я и есть тот схемотехник. biggrin.gif
Дело в том, что устройство находится внутри коммутационной ячейки, практически на корпусе ВВ. И коммутируется 10кВ.
Больших проблем там нет, примерно один сбой на 100 коммутаций, да и исправляется это программно. Так как я сам управляю ВВ, то для гарантии я запретил запись на 100мс после коммутации.
jcxz
Цитата(amiller @ Apr 21 2016, 18:14) *
Дело в том, что устройство находится внутри коммутационной ячейки, практически на корпусе ВВ. И коммутируется 10кВ.
Больших проблем там нет, примерно один сбой на 100 коммутаций, да и исправляется это программно. Так как я сам управляю ВВ, то для гарантии я запретил запись на 100мс после коммутации.

А пишете непрерывно? Или периодически? Если не тестили непрерывной записью с непрерывным контролем-же, то скорей всего у Вас не 1 сбой на 100 коммутаций, а 100 сбоев на 1-у коммутацию, просто попадают они в моменты пауз обмена по SPI laughing.gif
Скорей всего наводка идёт по питанию и надо её искать, а то изменится немного алгоритм работы, или окажется рядом другой такой-же вакуумник и сбои попрут косяками.
Наши схемотехники, когда проводят испытания на устойчивость к нано- и микросекундам, живут в лаборатории по несколько недель, вылазя из неё только на обед и кофепаузы wacko.gif
Пока не поборют полностью.
И счётчики наши и в 10-ках стоят и в 35-ках рядом с вакуумниками.

А так: цепи до флешки/фрамки покороче, подтяжка всех линий обязательно и лучше внешняя (внутренняя бывает слабой) ну и т.п. И можно гнать и 30 и 40МГц SCLK.
amiller
Спасибо за обмен мнениями.
Кстати, посмотрел со всех сторон на вариант с размещением кода в ОЗУ. И убедился, что действительно слишком много, если не всё, придётся перетаскивать в ОЗУ, чтобы программа могла работать в процессе стирания флэш. Стоит прочитать любую константу, и завис до окончания процесса.
В связи с этим снова начал смотреть в сторону внешней памяти. Только тип выбираю пока.

scifi
Цитата(amiller @ Apr 21 2016, 20:05) *
В связи с этим снова начал смотреть в сторону внешней памяти. Только тип выбираю пока.

Их есть у нас! Тут.
В пределах 25-й серии есть оч. высокая совместимость между разными производителями. И советую унифицировать посадочное место под SOIC-8 3,9 мм и 5,3 мм, чтобы выбор был пошире в случае чего.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.