реклама на сайте
подробности

 
 
10 страниц V  < 1 2 3 4 > »   
Reply to this topicStart new topic
> __LDREX __STREX в STM32F407
Forger
сообщение Jun 5 2017, 09:49
Сообщение #16


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(jcxz @ Jun 5 2017, 12:37) *
Вот именно....

Согласен, я поспешил с выводами sad.gif
Выходит, что в более приоритетных прерываниях нельзя использовать svc, а можно лишь в задачах/потоках. Этого я не знал ((

Я рассчитывал в реализациях программных очередей (queue) отказаться от критических секций (простое запрет/разрешение прерываний),
но коли в прерываниях это создает трудности (скажем, прерывание от usart), то выходит, что svc ипользовать не получится. А жаль ((
Или можно просто поднять приоритет svc до уровня чуть ниже важных прерываний (в которых запрещены вызовы серсвисов оси), тогда задача решится. Я прав?


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
_lexa_
сообщение Jun 5 2017, 10:17
Сообщение #17


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 23-03-15
Пользователь №: 85 852



Цитата(jcxz @ Jun 5 2017, 07:49) *
Если между LDREX и STREX произошло прерывание или был выполнен другой эксклюзивный доступ, до будет нарушение эксклюзивности.
Ну и где у вас между LDREX и STREX нарушение эксклюзивности?


Если смотреть по коду, который я привел - первый запрос на эксклюзивный доступ здесь:
CODE
void mpu_cfg_test()
{ ...
//выполняем запрос эксклюзивного доступа к переменной cur_mes.sync
DWORD sync=0;
sync = __LDREX(&cur_mes.sync);
__DMB();
soft_int_ini(); //настойка программного прерывания
soft_int_on(); //вызов программного прерывания
__WFI();
}


второй запрос в обработчике программного прерывания:
CODE
DWORD sync;
do
{
sync = __LDREX(&cur_mes.sync);
sync++;
sync = __STREX(sync, &cur_mes.sync);
}
while (sync);
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 5 2017, 10:59
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Forger @ Jun 5 2017, 11:49) *
Выходит, что в более приоритетных прерываниях нельзя использовать svc, а можно лишь в задачах/потоках. Этого я не знал ((

Надо только обеспечить, чтобы в любой точке вызова SVC текущий уровень приоритета прерывания был ниже чем у SVC. И были разрешены faults. Тогда не будет HF, а будет корректный вход в ISR SVC.

Цитата(Forger @ Jun 5 2017, 11:49) *
Я рассчитывал в реализациях программных очередей (queue) отказаться от критических секций (простое запрет/разрешение прерываний),
но коли в прерываниях это создает трудности (скажем, прерывание от usart), то выходит, что svc ипользовать не получится. А жаль ((
Или можно просто поднять приоритет svc до уровня чуть ниже важных прерываний (в которых запрещены вызовы серсвисов оси), тогда задача решится. Я прав?

Можно конечно, но ещё раз спрашиваю: зачем надевать трусы через голову?? laughing.gif
Ведь если уж никак нельзя запрещать прерывания, то есть механизм LDREX/STREX, который именно для этого и создан.
А SVC - даже из названия видно - это для вызова системных функций. Привилегированных.
Можно конечно работу с очередями (или что там ещё) вынести на этот уровень, но зачем??? Это будет во много раз медленнее и громоздко чем LDREX/STREX.

Цитата(_lexa_ @ Jun 5 2017, 12:17) *
Если смотреть по коду, который я привел - первый запрос на эксклюзивный доступ здесь

А что такое "запрос на эксклюзивный доступ"? Откуда Вы это взяли?? Нет такого понятия. Нет никаких запросов там.
Эксклюзивный доступ read-modify-write - это пара инструкций LDREX/STREX работающих с некоей переменной.
Эксклюзивно - это означает, что никто другой (другой процесс) не обращается к этой переменной между LDREX и STREX. А если это условие нарушается - это нарушение эксклюзивности.
В Вашем случае есть одна только пара LDREX/STREX, её эксклюзивный доступ никто не нарушает.
Похоже Вы совсем не поняли, что написано в мануале и для чего это вообще нужно. Перечитайте ещё раз.
Go to the top of the page
 
+Quote Post
Forger
сообщение Jun 5 2017, 11:00
Сообщение #19


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(jcxz @ Jun 5 2017, 13:50) *
Надо только обеспечить, чтобы в любой точке вызова SVC текущий уровень приоритета прерывания был ниже чем у SVC.

Это решаемо, просто, запрещается вызов SVC в критичных прерываниях, где запрещен вызов сервисов оси (соотв. assert).

Цитата
И были разрешены faults. Тогда не будет HF, а будет корректный вход в ISR SVC.

Не понял ((( Т.е. запрещенные faults нарушают нормальную работу SVC?


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 5 2017, 11:09
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Forger @ Jun 5 2017, 13:00) *
Не понял ((( Т.е. запрещенные faults нарушают нормальную работу SVC?

Естественно. Я же писал уже несколько раз:
Цитата(jcxz @ Jun 5 2017, 11:37) *
Если бы Вы открыли мануал на ядро, то узнали бы, что SVC является синхронным исключением. Т.е. - должно обработаться сразу же.
А если это не возможно (например - запрещены исключения или, как Вы советуете, оно вызвано внутри более приоритетного ISR), то будет активирован механизм эскалации до Hard Fault.

Ещё раз: если SVC по каким-то причинам не может быть активировано немедленно, будет эскалация до HF.
Считайте что SVC - это вызов функции. Если у Вас в коде идёт команда BL, то ведь процессор обязан её выполнить, он не может её перескочить.
То же самое и с SVC - это считается вызовом системной функции. Она не может быть не выполнена. А если запрещены fault-ы - значит активировать исключение нельзя. Из-за этого конфликта и будет эскалация до HardFault. Процессор будет стоять на SVC и повышать-повышать приоритет её до тех пор, пока не сможет выполнить. Он и повысит до HF, которое может выполнить даже с запрещёнными fault-ами.
Так как это синхронное прерывание, значит оно должно быть выполнено немедленно.
Go to the top of the page
 
+Quote Post
Forger
сообщение Jun 5 2017, 11:18
Сообщение #21


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(jcxz @ Jun 5 2017, 14:09) *
Так как это синхронное прерывание, значит оно должно быть выполнено немедленно.

Цитата(jcxz @ Jun 5 2017, 14:09) *
И были разрешены faults.

Речь как я понял идет про конкретно один fault - SVCall Handler. Или я опять не так понял?




--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Forger
сообщение Jun 5 2017, 12:22
Сообщение #22


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Попался полезный документ по теме:
http://infocenter.arm.com/help/topic/com.a..._primitives.pdf


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Jun 5 2017, 12:40
Сообщение #23


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(AHTOXA @ Jun 5 2017, 06:38) *
А в чём выгода такого метода по сравнению с простым запретом/разрешением прерываний? Я думаю, что по скорости это даже медленнее (тратится время на сохранение и восстановление контекста).
Прелесть же LDREX/STREX как раз в том, что они не блокируют прерывания.

Я не претендую на истину в последней инстанции и рассматриваю применение SVC в моих проектах как один из методов программирования с использованием предоставленных возможностей процессора. Ноги где-то растут из старых времен MS DOS и использованием INT 2F wink.gif.

Как кто-то в теме догадался, не люблю я всякие запреты-разрешения прерываний. Зачем меня должно в участке кода заботить, какие разрешены, а какие нет? Если работать с запретом и последующим разрешением общего прерывания, надо тоже хоть немного контекст сохранять: надо бы знать, а было ли вообще разрешено прерывание на момент необходимости его запрета, чтобы потом не разрешить случаем то, что было запрещено? Затем необходимо множить такие блоки во всех фрагментах, которые критическую секцию используют: хоть макросы напиши, код получается громоздкий для написания и понимания. Не нравится мне это чисто стилистически. На круг получится, что суммарный код обрамления критических секций станет больше обработчика SVC. Синтаксически - как следует из заголовка, который я привел, - я работаю с на вид обычными функциями, которые порождают единственную инструкцию.

И еще. Тут многие забалованы F4xx и выше. А у меня есть проекты на одной плате с опциональными F103 и F051 (ценообразование). Вы будете смеяться, но на Cortex-M0 F051 LDREX/STREX отсутствуют. А механизм SVC работает на обоих.

Сообщение отредактировал KnightIgor - Jun 5 2017, 12:50
Go to the top of the page
 
+Quote Post
_lexa_
сообщение Jun 5 2017, 13:26
Сообщение #24


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 23-03-15
Пользователь №: 85 852



Цитата(jcxz @ Jun 5 2017, 10:59) *
А что такое "запрос на эксклюзивный доступ"? Откуда Вы это взяли?? Нет такого понятия. Нет никаких запросов там.

например, отсюда:
"PM0214. STM32F3xxx and STM32F4xxx Cortex-M4 programming manual.
2.2.7 Synchronization primitives
...
A pair of synchronization primitives comprises:
● A Load-Exclusive instruction: Used to read the value of a memory location, requesting
exclusive access
to that location."

Цитата(jcxz @ Jun 5 2017, 10:59) *
Эксклюзивный доступ read-modify-write - это пара инструкций LDREX/STREX работающих с некоей переменной.
Эксклюзивно - это означает, что никто другой (другой процесс) не обращается к этой переменной между LDREX и STREX. А если это условие нарушается - это нарушение эксклюзивности.
В Вашем случае есть одна только пара LDREX/STREX, её эксклюзивный доступ никто не нарушает.

Эта пара нужна, чтобы монитор эксклюзивного доступа отметил выполнение LDREX, затем при выполнении STREX снял эту метку, разумеется при условии, что данной парой LDREX/STREX мы не влезли между LDREX и STREX другой части программы, например в случае возникновения прерывания. Если переписать код следующим образом:
Код
void mpu_cfg_test()
{    ...
        //выполняем запрос эксклюзивного доступа к переменной cur_mes.sync
    DWORD sync=0;
    sync = __LDREX(&cur_mes.sync);
    __DMB();
    soft_int_ini();    //настойка программного прерывания
    soft_int_on();    //вызов программного прерывания
    __WFI();
    __STREX(sync, &cur_mes.sync);
}

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

Цитата(jcxz @ Jun 5 2017, 10:59) *
Похоже Вы совсем не поняли, что написано в мануале и для чего это вообще нужно. Перечитайте ещё раз.

В таком случае, если не сложно, приведите, пожалуйста, небольшой пример кода, когда происходит нарушение эксклюзивности.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 5 2017, 13:47
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Forger @ Jun 5 2017, 13:18) *
Речь как я понял идет про конкретно один fault - SVCall Handler. Или я опять не так понял?

Бит разрешения на все fault-ы один общий.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 5 2017, 13:51
Сообщение #26


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(_lexa_ @ Jun 5 2017, 18:26) *
В таком случае, если не сложно, приведите, пожалуйста, небольшой пример кода, когда происходит нарушение эксклюзивности.

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


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
_lexa_
сообщение Jun 5 2017, 13:55
Сообщение #27


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 23-03-15
Пользователь №: 85 852



Цитата(Forger @ Jun 5 2017, 12:22) *
Попался полезный документ по теме:
http://infocenter.arm.com/help/topic/com.a..._primitives.pdf


Я тоже его нашел, сейчас как раз изучаю. Тема также освещена в ARMv7-M Architecture Reference Manual, где среди прочего написано про разделяемую память, про глобальный и локальный мониторы эксклюзивного доступа, многопроцессорность и т.д. Все эти документы ARM-овские.
У ST LDREX/STREX описаны в PM0214. STM32F3xxx and STM32F4xxx Cortex-M4 programming manual. Причем довольно коротко, многое не по какой-то причине не затронуто и даже ссылок на АРМ-овские документы не даны.
В общем, поизучав все это приходит мысль, что я просто в каком-то регистре не поставил какой-то флаг и у меня, например, не работает глобальный монитор.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 5 2017, 13:57
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(KnightIgor @ Jun 5 2017, 14:40) *
Если работать с запретом и последующим разрешением общего прерывания, надо тоже хоть немного контекст сохранять: надо бы знать, а было ли вообще разрешено прерывание на момент необходимости его запрета, чтобы потом не разрешить случаем то, что было запрещено?

void f1()
{
CPU_SR_ALLOCATE(); //выделение переменной (регистра) для сохранения состояния прерываний
ENTR_CRT_SECTION(); //вход в критическую секцию (запрет прерываний)
...
EXIT_CRT_SECTION(); //выход из критической секции (восстановление состояния прерываний)
}
void f2()
{
CPU_SR_ALLOCATE(); //выделение переменной (регистра) для сохранения состояния прерываний
ENTR_CRT_SECTION(); //вход в критическую секцию (запрет прерываний)
f1();
...
EXIT_CRT_SECTION(); //выход из критической секции (восстановление состояния прерываний)
f1();
}
Вот и всё отслеживание. Больше никаких проверок не нужно и можно вызывать сколько угодно вложенно - всё работает корректно.
ENTR_CRT_SECTION() - компилится в 2 команды CPU;
EXIT_CRT_SECTION() - компилится в 1 команду CPU.
Теперь сравните со своим огородом в десятки команд.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 5 2017, 13:58
Сообщение #29


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(KnightIgor @ Jun 5 2017, 17:40) *
Как кто-то в теме догадался, не люблю я всякие запреты-разрешения прерываний. Зачем меня должно в участке кода заботить, какие разрешены, а какие нет? Если работать с запретом и последующим разрешением общего прерывания, надо тоже хоть немного контекст сохранять: надо бы знать, а было ли вообще разрешено прерывание на момент необходимости его запрета, чтобы потом не разрешить случаем то, что было запрещено?


Ох, ну вот уж проблема так проблема sm.gif
Это может выглядеть, например, просто как объявление
Код
{
    TCritSect cs;
    ...
}

в начале блока кода. При выходе из блока прерывания автоматически возвращаются в исходное состояние.

Я не говорю, что ваш способ ошибочен, я говорю, что он не даёт преимуществ по сравнению с простым запретом/разрешением прерываний, и к тому же он (гораздо) медленнее. Думаю, что на маленьких процессорах (типа M0(+)) это может быть критично.
Кроме того, как тут выяснили, этот способ требует правильной расстановки приоритетов, а иначе способен вызвать HardFault.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 5 2017, 14:21
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(_lexa_ @ Jun 5 2017, 15:26) *
● A Load-Exclusive instruction: Used to read the value of a memory location, requesting
exclusive access
to that location."

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

Цитата(_lexa_ @ Jun 5 2017, 15:26) *
ничего не изменится (на всякий случай я это даже проверил). Каким образом монитор эксклюзивного доступа должен увидеть, что использована именно пара LDREX/STREX

Вот именно в таком случае - оно и сработает и обнаружит нарушение эксклюзивности.
Команда LDREX взводит некий триггер в "1". STREX атомарно сбрасывает его и, если в в момент своего выполнения триггер стоял - выполняет операцию, если не стоял - не выполняет. И возвращает соотв. значение.
Также любое прерывание сбрасывает этот триггер. А также команда CLREX тоже сбрасывает.
Вот и всё. Всё просто.
Go to the top of the page
 
+Quote Post

10 страниц V  < 1 2 3 4 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 21:53
Рейтинг@Mail.ru


Страница сгенерированна за 0.01478 секунд с 7
ELECTRONIX ©2004-2016