Jump to content

    

__LDREX __STREX в STM32F407

Изучать ядро нужно по первоисточнику http://infocenter.arm.com/help/index.jsp, а не по переводам и толкованиям. А в первоисточнике нет никаких "requesting".

В первоисточнике немного намудрили, так как объясняют концепцию применительно к многопроцессорным системам в том числе, а там несколько сложнее.

тынц

тынц

Share this post


Link to post
Share on other sites

Начали за упокой, кончили за здравие.

 

Как уже было сказано, LDREX выставляет атомарный флаг при использовании команды в потоке, конкретно на используемый адрес. Точнее конкретный адрес чтения выставляется на мониторе, и отслеживается аппаратными механизмами сразу на интерфейсе памяти.

Атомарный флаг может сбросить любое прерывание, любое аппаратное чтение/запись по этому адресу (например DMA).

Флаг не сбрасывается в момент применения команды LDREX в прерывании и перебивании его более высоким приоритетом. Отчего костыль для использования в прерывании содержит собственный сброс до и после.

STREX выполняется, или не выполняется без использования программной проверки атомарного флага, этот механизм выполнен полностью аппаратно.

STREX выдаёт флаг, видимый для программы - для проверки успешности операции.

 

Выполнение STREX в потоке - автоматически сбрасывает атомарный флаг, не важно какой результат успеха. Использование в прерывании STREX не гарантирует сброс, но успешно и корректно выставляет программный флаг для проверки операции. Мойте перед и зад - это есть костыль.

 

+Ещё один важный прикол - конвейер. Лучше перебздеть, и подтверждать полный сброс данных в память.

+Ещё грабли - LDREX STREX могут применяться на той памяти, что имеет прямое подключение к ядру мк. Например в М7 часть памяти заведена через ускоритель, в результате применение LDREX STREX моментально вешает мк.

 

------------

 

SVC - безусловное прерывание. Отрабатывается без вытеснения из любой позиции. Перебить SVC - просто невозможно.

SVC - это рыба для сервисов ОС, с небольшим количеством шаманства - превращается в очень удобную функцию.

У меня на SVC полностью работает собственная ось.

Share this post


Link to post
Share on other sites
Видимо это какое-то изобретение терминологии деятелей из STM. :laughing:

Изучать ядро нужно по первоисточнику http://infocenter.arm.com/help/index.jsp, а не по переводам и толкованиям. А в первоисточнике нет никаких "requesting".

 

Вот в первоисточнике ARMv7-M Architecture Reference Manual:

A3.4.2 Exclusive access instructions and Shareable memory regions.

Operation of the global monitor.

Load-Exclusive from Shareable memory performs a load from memory, and causes the physical address of

the access to be tagged as exclusive access for the requesting processor (эксклюзивный доступ для запрашивающего процессора)

 

Да и как не читать? Это целевой мануал, для процессора с которым я работаю.

 

Вот именно в таком случае - оно и сработает и обнаружит нарушение эксклюзивности.

Команда LDREX взводит некий триггер в "1". STREX атомарно сбрасывает его и, если в в момент своего выполнения триггер стоял - выполняет операцию, если не стоял - не выполняет. И возвращает соотв. значение.

Вот и всё. Всё просто.

Именно так я себе все это и представлял.

 

Вот тут посмотрите: тынц. И вообще всю тему посмотрите. Там очень подробно всё разобрали, с учётом особенностей STM32.

Спасибо за ссылку. Узнал много интересного.

Edited by _lexa_

Share this post


Link to post
Share on other sites
Спасибо за ссылку. Узнал много интересного. В частности, что LDREX/STREX, по крайней мере для STM32 на cortex-m4, не могут использоваться для синхронизации доступа к памяти, т.к. любое прерывание сбрасывает тег монитор и все дальнейшее выполнение программы происходит, как будто LDREX до этого не выполнялась. Бесполезность LDREX/STREX для синхронизации косвенно подтверждается еще и тем, что в CMSIS-RTOS эти команды в мутексах и семафорах не используются.

 

Сброс тег монитора из потока в прерывание - это нормальное поведение LDREX/STREX, именно для этого они и задумывались.

Нет широкого распространения по другой причине - память должна подключаться к ядру без цепочек ускорителей. То-есть команды LDREX/STREX гарантированно выполняются на всех arm чипах, но не на всей используемой памяти. Делить на можно/нельзя - слишком сложно, проще не использовать вовсе. Однако применение LDREX/STREX даёт очень ощутимое ускорение на операциях с атомарными флагами. Словом можно - если руки растут из нужного места.

Весь смысл в том чтобы не испортить другие флаги.

Share this post


Link to post
Share on other sites
Сброс тег монитора из потока в прерывание - это нормальное поведение LDREX/STREX, именно для этого они и задумывались.

Нет широкого распространения по другой причине - память должна подключаться к ядру без цепочек ускорителей. То-есть команды LDREX/STREX гарантированно выполняются на всех arm чипах, но не на всей используемой памяти. Делить на можно/нельзя - слишком сложно, проще не использовать вовсе. Однако применение LDREX/STREX даёт очень ощутимое ускорение на операциях с атомарными флагами. Словом можно - если руки растут из нужного места.

Весь смысл в том чтобы не испортить другие флаги.

Пожалуй я в самом деле погорячился по поводу невозможности синхронизации с помощью LDREX/STREX.

Share this post


Link to post
Share on other sites

У меня вопросы по Вашему примеру.

Что будет, если после сохранения текущего статуса разрешения прерываний в выделеной переменной (оно было разрешено), но до исполнения самой инструкции запрета прерывания произойдет-таки прерывание, которое по какой-либо логике всей программы запретит прерывания? Как я понимаю, после выхода из критической секции прерывание будет-таки разрешено , т.к. будет восстановлено из переменной?

Edited by KnightIgor

Share this post


Link to post
Share on other sites
Как уже было сказано, LDREX выставляет атомарный флаг при использовании команды в потоке, конкретно на используемый адрес. Точнее конкретный адрес чтения выставляется на мониторе, и отслеживается аппаратными механизмами сразу на интерфейсе памяти.

Атомарный флаг может сбросить любое прерывание, любое аппаратное чтение/запись по этому адресу (например DMA).

Монитор эксклюзивного доступа не контролирует адрес. Об этом явно сказано в мануале.

Да и как вы это себе представляете? Если у процессора 4гига адресное пространство - это-ж нужна 4^32 триггеров иметь в CPU - для каждого адреса.

Опять-же - любое чтение/запись не может и не должно. Может только STREX, CLREX или любое изменение текущего уровня прерывания.

DMA, как и прочие bus-master-ы, тоже не должны влиять - они не относятся к ядру процессора.

 

т.к. любое прерывание сбрасывает тег монитор и все дальнейшее выполнение программы происходит, как будто LDREX до этого не выполнялась.

И что???

Так в этом и заключается вся полезность LDREX/STREX! Именно для того оно и предназначено - если между LDREX и STREX было прерывание (или переключение контекста, которое тоже выполняется через прерывание), то значит - нет гарантии, что операция чтение-модификация-запись была эксклюзивной.

Похоже Вы так и не поняли зачем нужен и как работает этот эксклюзивный доступ... :(

 

Бесполезность LDREX/STREX для синхронизации косвенно подтверждается еще и тем, что в CMSIS-RTOS эти команды в мутексах и семафорах не используются.

Они и не должны там использоваться если ОС должна быть мультиплатформенной. Они могут использоваться в портах ОС.

Понятно - все дураки, и создатели ядра и создатели IAR-а например, да все кто поддерживает эти LDREX/STREX - не понимают они их бесполезность. Объясните им :biggrin:

 

Нет широкого распространения по другой причине - память должна подключаться к ядру без цепочек ускорителей. То-есть команды LDREX/STREX гарантированно выполняются на всех arm чипах, но не на всей используемой памяти.

Эксклюзивный доступ нужен не к массивам памяти, а к отдельным переменным, коих в программе обычно мало. Достаточно вынести их в отдельный регион памяти и объявить его некешируемым (через MPU).

 

Что будет, если после сохранения текущего статуса разрешения прерываний в выделеной переменной (оно было разрешено), но до исполнения самой инструкции запрета прерывания произойдет-таки прерывание, которое по какой-либо логике всей программы запретит прерывания? Как я понимаю, после выхода из критической секции прерывание будет-таки разрешено , т.к. будет восстановлено из переменной?

Ну наверное.

А что это за прерывание такое, которое внутри себя запрещает прерывания??? Аппаратное асинхронное?

Т.е. - оно может вызваться в любой точке и в произвольный момент времени запретить прерывания?

А зачем это нужно и как может такая программа вообще функционировать?

Share this post


Link to post
Share on other sites
Похоже Вы так и не поняли зачем нужен и как работает этот эксклюзивный доступ... :(

AVI-crak доходчиво объяснил:

Сброс тег монитора из потока в прерывание - это нормальное поведение LDREX/STREX, именно для этого они и задумывались.

 

Они и не должны там использоваться если ОС должна быть мультиплатформенной. Они могут использоваться в портах ОС.

Понятно - все дураки, и создатели ядра и создатели IAR-а например, да все кто поддерживает эти LDREX/STREX - не понимают они их бесполезность. Объясните им :biggrin:

Я же чуть ниже написал, что погорячился. И сообщение поправил, чтоб глаза не резало.

Share this post


Link to post
Share on other sites
Монитор эксклюзивного доступа не контролирует адрес. Об этом явно сказано в мануале.

Да и как вы это себе представляете? Если у процессора 4гига адресное пространство - это-ж нужна 4^32 триггеров иметь в CPU - для каждого адреса.

Там всё просто, один единственный 32b регистр и схема сравнения на коммутаторе памяти, уже после арбитра и коммутатора нагрузки. Эти команды не выполняются целиком и полностью в ядре мк, они большей частью размазаны по всему кристаллу.

Точно так-же как и команды DSB, ISB, ISB, WFE, и так далее.

Share this post


Link to post
Share on other sites
Там всё просто, один единственный 32b регистр и схема сравнения на коммутаторе памяти, уже после арбитра и коммутатора нагрузки. Эти команды не выполняются целиком и полностью в ядре мк, они большей частью размазаны по всему кристаллу.

Открываем мануал на M4, читаем:

"The Cortex-M4 processor implements a local exclusive monitor. The local monitor within the processor

has been constructed so that it does not hold any physical address, but instead treats any access as

matching the address of the previous LDREX. This means that the implemented exclusives reservation

granule is the entire memory address range."

Фантазии про некий регистр рассеиваются :laughing:

Влияние доступов от DMA и прочих bus-masters на exclusive monitor - также представляется крайне сомнительным, так как:

1. зачем оно нужно?

2. где про это сказано?

3. exclusive monitor относится к ядру, а DMA- и прочие bus-masters к ядру не относятся и у каждого МК-мэйкера свои.

Share this post


Link to post
Share on other sites
Ну наверное.

То есть, предложенное решение не на все случаи? Вы также признаете очевидность, Мистер Андерсон? ;)

 

А что это за прерывание такое, которое внутри себя запрещает прерывания??? Аппаратное асинхронное?

Т.е. - оно может вызваться в любой точке и в произвольный момент времени запретить прерывания?

А зачем это нужно и как может такая программа вообще функционировать?

Да кто же его знает! Однако, такое возможно. Например, прерывание, сделав дело и установив флаг, запрещает прерывания до момента, пока синхронная часть не обработает флаг и не сочтет нужным прерывание снова разрешить. И Ваш код породит огород, на котором пожнут не то, что сеяли.

Edited by KnightIgor

Share this post


Link to post
Share on other sites
1. зачем оно нужно?

2. где про это сказано?

3. exclusive monitor относится к ядру, а DMA- и прочие bus-masters к ядру не относятся и у каждого МК-мэйкера свои.

Это результат проверки с отладчиком на реальном камне М3-7. В последнее время я чаще доверяю собственным экспериментам, чем расплывчатому переводу гугла.

Кстати, чтобы убрать последствия действий самого отладчика - точки останова необходимо ставить за пределами тестовой функции, иначе будут увлекательные результаты.

 

 

Да кто же его знает! Однако, такое возможно. Например, прерывание, сделав дело и установив флаг, запрещает прерывания до момента

 

Находясь в прерывании нельзя запретить само прерывание, получите сбой. Однако можно сбросить те сработавшие прерывания - что имеют более низкий приоритет, те что находятся в ожидании. Но не те что уже сработали и были вытеснены. Иначе будет разрушение стека.

Кстати, эти действия могут понадобится в случае просто огромного кода в теле прерывания. То-есть нужно сначала создать себе проблемы, и только потом героически их решать.

Юзайте SVC, и будет вам счастье.

Share this post


Link to post
Share on other sites
То есть, предложенное решение не на все случаи? Вы также признаете очевидность, Мистер Андерсон? ;)

Для каких-то высосанных из пальца случае разве что. Для реальных задач из жизни - бесполезно.

 

Да кто же его знает! Однако, такое возможно. Например, прерывание, сделав дело и установив флаг, запрещает прерывания до момента, пока синхронная часть не обработает флаг и не сочтет нужным прерывание снова разрешить. И Ваш код породит огород, на котором пожнут не то, что сеяли.

Вы сами-то хоть верите в то, что пишете? У Вас реально были такие алгоритмы? Или может у кого-то из здесь присутствующих (чайников не считаем)?

Конечно - можно лисапет и с 5-ю колёсами изобрести. Ездить будет? Ну а почему бы и нет. Нужно это кому-то реально? Вопрос риторический.

А если на дороге встретится 2 ямки - лисапет с 2-я колёсами ведь в них провалится, а с 5-ю - нет! Это значит что 2-колёсный лисапет никуда не годится и все кто на нём ездят - идиоты, а кто на 5-колёсном - умные?

И можно ещё напридумывать кучу причин, почему 2-колёсный плох. Только все почему-то на нём ездят и не жужжат, а у Вас - не получается никак и Вам обязательно нужен 5-колёсный :laughing:

 

эти действия могут понадобится в случае просто огромного кода в теле прерывания.

В этом случае надо просто перенести этот код в задачу ОС и всё.

Да и без ОС можно решить задачу нормально: возбудив программное прерывание с меньшим приоритетом и продолжив работу там, отпустив аппаратный ISR.

Как видно - для всего есть штатные решения, а необходимость запрета прерываний внутри ISR - высосана из пальца.

 

Это результат проверки с отладчиком на реальном камне М3-7. В последнее время я чаще доверяю собственным экспериментам, чем расплывчатому переводу гугла.

А зачем Вам нужно, чтобы DMA-операция влияла на монитор эксклюзивности? Ну т.е. - реально, а не по надуманным причинам?

Share this post


Link to post
Share on other sites
Юзайте SVC, и будет вам счастье.

Это не по адресу: я и так юзаю - почитайте сначала. Меня отговаривают и предлагают варианты, которые не всегда работоспособны.

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

Я предполагаю, что это Вы сгоряча. Очень даже легко можно запретить прерывание, находясь в нем. Без последствий.

 

Для каких-то высосанных из пальца случае разве что. Для реальных задач из жизни - бесполезно.

Почитайте Мерфи: если что-то может случиться, оно случится.

Вы сами-то хоть верите в то, что пишете?

Инженерная наука не оперирует понятием веры. Есть факты, есть опыт. ОТ: правда, слышал, что ныне за такое высказывание в РФ и сесть можно.

Как видно - для всего есть штатные решения, а необходимость запрета прерываний внутри ISR - высосана из пальца.

Утверждение более чем недальновидное.

Рассмотрим пример. Сразу оговорюсь, что речь не о глобальном запрете прерывания, а о запрете периферийного. Но и Вы пишете об ISR вообще.

 

В прерывании от устройства обнаруживается, что буфер приема заполнен, т.е. недовыбран синхронным циклом. Есть два варианта: выбросить данные или таки еще немного подождать, дать возможность выбрать, тем более, что передача данных по каналу сама по себе требует времени, и можно успеть до переполнения периферийного регистра. Одно из решений: запретить прерывание, оставив флаг, выйти, дать синхронному циклу поработать. Синхронный цикл после выбоки данных просто разрешает прерывание снова. Поскольку флаг взведен, прерывание щелкнет незамедлительно еще раз, данные будут записаны в освободившееся место. Это одно из возможных решений, которое я никому не навязываю. У меня так работают многие каналы. На результаты жалоб нет.

 

Edited by KnightIgor

Share this post


Link to post
Share on other sites
Открываем мануал на M4, читаем:

"The Cortex-M4 processor implements a local exclusive monitor. The local monitor within the processor

has been constructed so that it does not hold any physical address, but instead treats any access as

matching the address of the previous LDREX. This means that the implemented exclusives reservation

granule is the entire memory address range."

судя по этому абзацу да по остальному в мануалах (применительно к cortex-m4) для синхронизации на LDREX/STREX достаточно одной единственной ячейки памяти, которую будут читать/писать LDREX/STREX, на весь исполняемый процессором код. А для STM32f4 даже настройки MPU не потребуется (кэша на RAM там нет)

 

Влияние доступов от DMA и прочих bus-masters на exclusive monitor - также представляется крайне сомнительным, так как:

Я так понимаю, AVI-crak просто провел эксперимент, в результате которого DMA сбросил тэг монитора, и здесь не стоит вопрос нужно ли это или не нужно. По поводу того, где это сказано, конечно не совсем про то, но в принципе сюда можно взглянуть:

ARMv7-M Architecture Reference Manual

A3.4.5 Load-Exclusive and Store-Exclusive usage restrictions

• An explicit store to memory can cause the clearing of exclusive monitors associated with other

processors, therefore, performing a store between the LDREX and the STREX can result in a livelock

situation. As a result, code must avoid placing an explicit store between an LDREX and an STREX in a

single code sequence.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this