Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32L151 инструкции dsb isb и т.п.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
MiklPolikov
Посматривал код операционки freeRTOS , и обнаружил там
__dsb( portSY_FULL_READ_WRITE );
__wfi();
__isb( portSY_FULL_READ_WRITE );
как я понимаю, перед остановкой процессора команда dsb дожидается завершения всех текущих команд в конвеере.
что делает isb после выхода из сна понимаю совсем смутно.
Не понимаю, почему именно эти две команды, ведь в описании ядра есть и другие подобные команды-барьеры.
Очень хотелось бы понять эту премудрость.

И вот ещё:
При переключении тактовой частоты с 1MHz на 16MHz и обратно процессор иногда зависает. А если между 1 и 16 МГц включать "промежуточную" 4МГц, то проблемы нет.
Может как раз при переключении частоты и нужно применить какую-то барьерную команду ?

Заранее спасибо за ответы !
Golikov A.
переключение частот как? просто меняете делитель и все что ли?

правильно частоты менять так
переходите на внутреннее тактирование
настраиваете новую частоту
ждете стабилизации ПЛЛ
переходите на тактирование от него

в момент перестройки может быть что угодно, клоки любой длинны, и все сработает как попало, наличие другой частоты ИМХО просто делает скачки более плавными, и в конкретно ваших условиях это помогло. Но в температуре, диапазоне питаний может быть косяк...
SII
В STM32Lxxx надо ещё следить за напряжением питания процессорного ядра и настройками флэш-памяти -- к ним разные требования на разных частотах. В документации всё описано, включая последовательность действий, необходимых для изменения частоты.
MiklPolikov
Цитата(SII @ May 4 2014, 12:22) *
В STM32Lxxx надо ещё следить за напряжением питания процессорного ядра и настройками флэш-памяти -- к ним разные требования на разных частотах. В документации всё описано, включая последовательность действий, необходимых для изменения частоты.

Пока генератор стабилизируется жду. А voltage range 1 для того что бы настройки FLASH можно было не трогать.
И всё равно при переключении 1-16-1 МГц виснет. А при переключении 1-4-16-4-1 МГц не виснет даже при Voltage Range 2 и 3 .
Уже обсуждал тут тему частот и всех сопутствующих настроек. http://electronix.ru/forum/index.php?showt...likov&st=15
Пока получается, что единственная защита от глюка это "постепенное" переключение с промежуточной частотой.
SII
Пока PLL не "устаканилась" на новой частоте, на её выходе может твориться любое безобразие. Соответственно, на время перенастройки PLL необходимо переходить на тактирование процессора от другого источника. 4 МГц, если память не изменяет, выдаёт MSI, но можно использовать и внешний кварц/осциллятор (HSE), если он уже был запущен: переключение же режимов PLL не влияет на собственно генератор синхронизации. Так что в общем случае с одной частоты на другую действительно не перейдёшь без промежуточной частоты, получаемой без PLL.
Golikov A.
есть мнение что PLL при резкой смене частоты с 1 на 16 и на 1, выдает сигнал что оно устаканилось а потом срывается.
jcxz
Цитата(Golikov A. @ May 7 2014, 13:56) *
есть мнение что PLL при резкой смене частоты с 1 на 16 и на 1, выдает сигнал что оно устаканилось а потом срывается.

В STM32??? biggrin.gif
MiklPolikov
Цитата(SII @ May 7 2014, 11:13) *
Пока PLL не "устаканилась" на новой частоте, на её выходе может твориться любое безобразие. Соответственно, на время перенастройки PLL необходимо переходить на тактирование процессора от другого источника. 4 МГц, если память не изменяет, выдаёт MSI, но можно использовать и внешний кварц/осциллятор (HSE), если он уже был запущен: переключение же режимов PLL не влияет на собственно генератор синхронизации. Так что в общем случае с одной частоты на другую действительно не перейдёшь без промежуточной частоты, получаемой без PLL.


Разумеется я это понимаю, и в точности так и обращаюсь с PLL
В данном случае наблюдаю глюк при переключении c давно работающих HSI 16 МГц на MSI 1 МГц и обратно.
Возможно, дело в "состыковке" фронтов двух несинхронизированных геренаторов. В момент переключения появляется очень короткий такт, он и вызывает сбой.
jcxz
Цитата(MiklPolikov @ May 7 2014, 18:21) *
Возможно, дело в "состыковке" фронтов двух несинхронизированных геренаторов. В момент переключения появляется очень короткий такт, он и вызывает сбой.

Если Вы "в точности так и обращаетесь", то в момент такой состыковки если даже это есть, ядро у вас будет работать от
дефолтного источника (не от PLL), и на него этот такт никак не должен повлиять.

А почему бы Вам переключение частоты не делать с предварительной перезагрузкой всего МК (аппаратным ресетом)?
Я в своём проекте, где тоже нужно переключать частоту PLL, не стал усложнять, и просто делаю аппаратный ресет,
а старт ПО и инициализация PLL идёт уже на новой clk.
Всё работает прекрасно с какой-бы на какую-бы частоту не пробовал переключаться. LPC1758
Golikov A.
Цитата
В данном случае наблюдаю глюк при переключении c давно работающих HSI 16 МГц на MSI 1 МГц и обратно.


Ё-МОЁ! Вы так описали, я подумал что когда вы частоту PLL меняете с 16 на 1 и возвращаетесь на него все падает... Потому и выссказал предположение о срыве... А в инструкции не описано спец последовательности переключения между HSI, MSI?

Цитата
Всё работает прекрасно с какой-бы на какую-бы частоту не пробовал переключаться. LPC1758

ну так на то он и LPC а не STM sm.gif...
MiklPolikov
Цитата(Golikov A. @ May 7 2014, 23:36) *
Ё-МОЁ! Вы так описали, я подумал что когда вы частоту PLL меняете с 16 на 1 и возвращаетесь на него все падает... Потому и выссказал предположение о срыве... А в инструкции не описано спец последовательности переключения между HSI, MSI?


В документе "PM0062 Flash and EEPROM Programming"
Но не до конца понимаю порядок переключения LATENCY и ACC64. Как понимаю я, при Voltage Range 1 о них заботится не нужно. Т.е. при высоком напряжении питания ядра и/или низкой частоте работает при любой настройке этих бит. В другом случае невозможно было бы сделать переключение, не пройдя через запрещённое сочетание настроек.


Increasing the CPU frequency (in the same voltage range).
● Program the 64-bit access by setting the ACC64 bit in FLASH_ACR
● Check that 64-bit access is taken into account by reading FLASH_ACR
● Program 1 WS to the LATENCY bit in FLASH_ACR
● Check that the new number of WS is taken into account by reading FLASH_ACR
● Modify the CPU clock source by writing to the SW bits in the RCC_CFGR register
● If needed, modify the CPU clock prescaler by writing to the HPRE bits in RCC_CFGR
● Check that the new CPU clock source or/and the new CPU clock prescaler value is/are
taken into account by reading the clock source status (SWS bits) or/and the AHB
prescaler value (HPRE bits), respectively, in the RCC_CFGR register
Decreasing the CPU frequency (in the same voltage range).
● Modify the CPU clock source by writing to the SW bits in the RCC_CFGR register
● If needed, modify the CPU clock prescaler by writing to the HPRE bits in RCC_CFGR
● Check that the new CPU clock source or/and the new CPU clock prescaler value is/are
taken into account by reading the clock source status (SWS bits) or/and the AHB
prescaler value (HPRE bits), respectively, in the RCC_CFGR register
● Program the new number of WS to the LATENCY bit in FLASH_ACR
● Check that the new number of WS is taken into account by reading FLASH_ACR
● Program the 32-bit access by clearing ACC64 in FLASH_ACR
● Check that 32-bit access is taken into account by reading FLASH_ACR
MiklPolikov
Коллеги, добрый день.

Сейчас вопрос исключительно про барьерные команды.
Хочу понять, в каких случаях они нужны.
Что они делают примерно понимаю, но общей ясной нет.
Кто разобрался в этом вопросе, просветите пожалуйста.


Сейчас понимаю так:
1) Если производится 1-включение тактирования периферии 2-запись чего-то в регистр периферии, то между этими командами нужна __isb(15), потому что если ещё не была выполнена 1, то 2 не пройдёт.

2) Аналогично п 1) нужно делать всё работу с аппаратной частью в местах, где выполнение предыдущей команды критически важно для последующей.

3) Несколько любых инструкций, например пустой цикл for ( i = 0 ; i < 5 ; i + + ) { } являются аналогом __isb(15); __dsb(15);

4) Между командами x=1; if( x == 1) {} барьерная команда не нужна, потому что компилятор сам знает, что их критически важно выполнить по очереди.

5) Если пример 4) реализовать каким-то хитрым образом через указатели, то быть может, для его гарантированной работы потребуется барьерная команда.

5)Предполагаю, что __dsb(15); оказывает действие в случаях, когда обращения к памяти происходят не по команде процессора, например в память что-то пишет периферия, или работает DMA .

Заранее спасибо за ответ !
adnega
Цитата(MiklPolikov @ Feb 24 2015, 23:01) *
Сейчас вопрос исключительно про барьерные команды.

Думаю, рояля играет в первую очередь в многопроцессорных системах.

Хотелось бы начать с более-менее внятного и повторяемого примера, где замена барьерной инструкции на NOP будет отличаться поведением.
Кто-нить писал самомодифицирующийся код для Cortex-M ? Может, без ISB не заработает?
aaarrr
1. Здесь нужна DSB, а не ISB. ISB может понадобиться, например, при выполнении действий типа remap, работе с MPU и т.п.

2. Опять-таки DSB, а не ISB в большинстве случаев.

3. На ARM7, например, так и делалось.

4. Не нужна, если x не является периферийным регистром.

5. Нет, если x не является периферийным регистром.

6. Нет.

ISB сбрасывает конвейер. Ставится после инструкции, выполнение которой может повлечь нарушение нормальной работы конвейера.
DSB заставляет ядро закончить все текущие операции с памятью до выполнения следующей инструкции.
DMB позволяет определить последовательность обращений к памяти, т.е. обращения, стоящие до барьера, будут гарантированно выполнены перед теми, что стоят после.

Цитата(adnega @ Feb 24 2015, 23:55) *
Хотелось бы начать с более-менее внятного и повторяемого примера, где замена барьерной инструкции на NOP будет отличаться поведением.
Кто-нить писал самомодифицирующийся код для Cortex-M ? Может, без ISB не заработает?

Одного NOP'а мало - конвейер длиннее. Самомодифицирующияся код без ISB работать не должен (хотя, если честно, не приходило в голову писать его для CM).
jcxz
Цитата(aaarrr @ Feb 25 2015, 03:04) *
Одного NOP'а мало - конвейер длиннее. Самомодифицирующияся код без ISB работать не должен (хотя, если честно, не приходило в голову писать его для CM).

Для создания такого кода, достаточно указать функции модификатор __ramfunc в IAR wink.gif

Цитата(aaarrr @ Feb 25 2015, 03:04) *
ISB сбрасывает конвейер. Ставится после инструкции, выполнение которой может повлечь нарушение нормальной работы конвейера.
DSB заставляет ядро закончить все текущие операции с памятью до выполнения следующей инструкции.
DMB позволяет определить последовательность обращений к памяти, т.е. обращения, стоящие до барьера, будут гарантированно выполнены перед теми, что стоят после.

Тогда для случая N.1 логичнее использовать DMB.
demiurg_spb
Цитата(MiklPolikov @ Feb 24 2015, 23:01) *
Хочу понять, в каких случаях они нужны.
В контексте STM32 использовал их лишь перед выходом из прерывания сразу после очистки его флага-запроса, чтобы при выходе снова не влететь в уже отработанное прерывание. Так на память больше ничего не приходит.
MiklPolikov
Цитата(demiurg_spb @ Feb 25 2015, 13:08) *
В контексте STM32 использовал их лишь перед выходом из прерывания сразу после очистки его флага-запроса, чтобы при выходе снова не влететь в уже отработанное прерывание. Так на память больше ничего не приходит.

Полезный совет ! К примеру, у меня многочисленные прерывания от дребезга кнопок всегда глючно обрабатываются, приходится RC ячейку ставить. Причём глючность очень походила на ту ситуацию, которую Вы описали. Использовали ISB ?
aaarrr
Цитата(jcxz @ Feb 25 2015, 08:45) *
Для создания такого кода, достаточно указать функции модификатор __ramfunc в IAR wink.gif

Однократное копирование и модификация в процессе выполнения - это не одно и то же.


Цитата(MiklPolikov @ Feb 25 2015, 13:25) *
Полезный совет ! К примеру, у меня многочисленные прерывания от дребезга кнопок всегда глючно обрабатываются, приходится RC ячейку ставить. Причём глючность очень походила на ту ситуацию, которую Вы описали. Использовали ISB ?

У Вас кнопки на десятках МГц дребезжат?

Лучше обратиться к мануалу. Там перечислены все те немногочисленные случаи, когда барьеры нужны на Cortex-M.
demiurg_spb
Цитата(MiklPolikov @ Feb 25 2015, 13:25) *
Использовали ISB ?
DSB
jcxz
Цитата(aaarrr @ Feb 25 2015, 16:34) *
Однократное копирование и модификация в процессе выполнения - это не одно и то же.

Однократное или многократное - не важно, какая разница - один раз сбой может произойти или много раз?
Если есть самомодификация (хоть одна) - нужен барьер. ISB.
aaarrr
Цитата(jcxz @ Feb 26 2015, 06:52) *
Однократное или многократное - не важно, какая разница - один раз сбой может произойти или много раз?

Просто ситуация с немедленным переходом на только что скопированный код очень маловероятна.

Цитата(jcxz @ Feb 26 2015, 06:52) *
Если есть самомодификация (хоть одна) - нужен барьер. ISB.

Тогда уж DSB + ISB.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.