|
|
  |
Атомарность чтения, в Cortex M3 |
|
|
|
Apr 2 2014, 09:04
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата 2.1. Установить флаг. 2.2. Выполнить действия. 2.3. Сбросить флаг. 2.4. (Пере)разрешить прерывание от источника данных. а чем это отличается от запрета прерывания перед входом в критическую секцию, и разрешением его после выхода? 2.1. запретить прерывание (не все, а конкретное) 2.2. Выполнить действия. 2.3. Разрешить прерывание (не все, а конкретное) прерывание вызванное до 2.1 и после 2.3 также как в вашем случае вызванное до 2.1 и после 2.4 прерывание между 2.1 - 2.2 и 2.2 - 2.3 не будет вызвано, его вызов отложиться до после 2.3, А в вашем случае прерывание между 2.1 - 2.2 и 2.2 - 2.3 будет вызвано, в нем оно себя запретит, выйдет, после чего будет также не вызываться, до окончания 2.4 и кого вы обманули  ? сами себя, напихав доп действий%)? это мне надо было в гугле найти?
|
|
|
|
|
Apr 2 2014, 09:33
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(Golikov A. @ Apr 2 2014, 10:04)  а чем это отличается от запрета прерывания перед входом в критическую секцию, и разрешением его после выхода? Разница есть. Речь о том, кто запрещает прерывание: конкурент (это плохо) или сам обработчик (он в курсе, и это лучше). Запрет прерывания в основной программе (скорее всего, некоем быстром цикле) происходил бы всегда и безусловно, и во время критической секции прерывание вообще бы не сработало. В моем же методе прерывание, как основной поставщик асинхронных данных, имеет приоритет, т.к. не запрещается извне, а само контролирует ситуацию, откладывать себя или нет. Кстати, такой же подход (когда конкурент за ресурс не запрещает, а разрешает прерывание) работает у меня в системе с двумя RF модулями на одной SPI-шине (конечно, каждый с собственным chip select): каждый модуль вырабатывает прерывание, которое должно слизать из него принятые данные. Но и основная программа может инициировать синхронный обмен с модулями. Что будет, если основная программа как раз обменивается с другим модулем, шина SPI занята, а первому модулю срочно приспичило? Нужно отложить прерывание, а конкурент, закончив обмен по SPI, его всегда переразрешает. Если оно было отложено, оно сработает. Такой подход, кстати, исключает также и взаимную блокировку, т.к. конкурент за ресурс ничего не запрещает. P.S. Не Вам, а ТС в Гугле найти. Я никого не собираюсь переубеждать. Я рассказываю, как это работает у меня.
Сообщение отредактировал KnightIgor - Apr 2 2014, 09:35
|
|
|
|
|
Apr 2 2014, 11:48
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
давайте еще раз, я чего то не понимаю моя последовательность действий 1. запрет прерывания 2. обработка 3. разрешение прерывания. в случае прерывания до 1 или после 3 все работает в случае прерывания 1-2, 2-3 обработка прерывания откладывается до после 3, и там обрабатывается ваша последовательность действий 1. ставим флаг 2. обработка 3. снятие флага. 4. разрешение прерывания в случае до 1 и после 4 все работает в случае прерывания 1-2, 2-3, 3-4, прерывание вызывается, запрещает себя, выходит из прерывания, продолжает обработка, а прерывание откладывается до после 4, где повторно вызывается и обрабатывается. результат один, прерывание работает либо до либо после критического куска, прерывание не работает внутри куска, все вызовы внутри откладываются до окончания куска. но при этом в вашем варианте вы делаете лишний вызов прерывания со всеми сохранениями регистров, у вас добавлен лишний флаг, в прерывании сделана лишняя проверка. Почему это лучше? Что разница есть это очевидно, но почему эта разница полезная?! что я упускаю? Цитата Разница есть. Речь о том, кто запрещает прерывание: конкурент (это плохо) или сам обработчик (он в курсе, и это лучше). это сильно зависит от обработчика, если он выполняет одно короткое действие, то он вообще не должен быть в курсе чего либо. А если есть два конкурирующие за ресурс устройства, то должен быть арбитр, который как раз решает приоритеты доступа. И я не уверен что назначать арбитром само прерывание (считай нагружать его еще дополнительным функционалом) правильно.
|
|
|
|
|
Apr 2 2014, 14:27
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(Golikov A. @ Apr 2 2014, 12:48)  давайте еще раз, я чего то не понимаю результат один, прерывание работает либо до либо после критического куска, прерывание не работает внутри куска, все вызовы внутри откладываются до окончания куска. Выделенным жирно в цитате - КЛЮЧЕВОЙ МОМЕНТ, в котором и заключается разница методов: - при запрете прерывания перед критической секцией в основной программе (Ваш вариант) ВХОДА в прерывание действительно не будет, как Вы и написали выше. Мне такое поведение алгоритма не нравится, т.к. это есть блокировка со стороны конкурента. - в моем варианте вход в прерывание происходит даже внутри критической секции конкурента, то есть прерывание РАБОТАЕТ внутри куска. И именно прерывание решает, что делать, поняв, что прервало критическую секцию. В простейшем случае - отложить саму себя.
|
|
|
|
|
Apr 2 2014, 16:15
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
По-моему, задача обработки фифо решена была несколько раньше, чем я пошёл в школу. А мне уже 47. Стандартно делается 2 указателя на начало и конец. Прерывание работает с указателем на конец, а голова с указателем на начало. Критическим является лишь сравнение указалей для контроля "перехлёста", если это принципиально возможно (например при управлении потоком и т.п.) Это 1 оператор. Его лучше защитить критической секцией. Это самый простой способ. Стиральная доска, надёжнее чем стиральная машина. Усложнение программы не ведёт к увеличению её надёжности в целом. Всегда существует какой-то баланс. Поэтому я разделяю позицию Golikov A.. Усложнение программы должно быть обосновано. Надёжностью, наглядностью, прочими критериями. Рассуждения KnightIgor мне показались неубедительными ...
|
|
|
|
|
Apr 3 2014, 03:57
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(SasaVitebsk @ Apr 2 2014, 20:15)  Рассуждения KnightIgor мне показались неубедительными ... Ну отчего же? Тоже вполне себе решение. Кстати, существенно уменьшающее латентность системы в целом. Когда-то это может быть чуть ли не единственным выходом из ситуации (безотносительно примера с fifo). Правда, практически того же эффекта можно добиться запрещая-разрешая прерывание _конкретного_ источника, а не всех прерываний в фоновой задаче. Избирательность - это хорошо.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Apr 3 2014, 06:52
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата И еще: кто-нить пользуется SVC? Может, лучше через SVC, раз "лишние" прерывания KnightIgor не напрягают? начинаю ненавидеть аббревиатуры, впечатление что все в курсе, а ты один дурак не понимаешь о чем речь. SVS - это че? Цитата Так вот в момент определения уровня заполнения буфера, необходимо сравнивать 2 указателя. В общем случае требуется критическая секция. только на момент выбора этих указателей из памяти, да и то только в том случае если указатель выбирается не за 1 такт. В этом случае пока вы считываете указатель между вашими командами может что-то влезть и вы получите начало указателя верное, а конец нет. В прочих случаях вы максимум получите прошлое значение указателя, и достаточно ввести запас, снимать сигнал готовности на 90% а не на 99.9% и всех делов. Пользуюсь золотым правилом менять переменные только в одном месте, это ограждает от многих проблем прерываний. То есть если есть прерывание которое добавляет данные и есть процесс который данные забирает, многие делают что прерывание добавило данные и счетчик данных увеличило, процесс забрал данные и счетчик уменьшил - это не верное решение, потому что на время процесса всегда надо блокировать прерывание. А если каждый процесс меняет только свою переменную, а другой ее только читает, то при атомарном выборе данных из памяти запретов прерывания не нужно. Поразмыслив над подходом KnightIgor увидел только один бонус, ему не надо думать в коде какие прерывания надо запретить на время критической секции, он просто отмечает вид секции, а все прерывания которые могут повредить этот вид секции выключат сами себя. Однако в конце секции ему все равно приходиться вспоминать все что могло отключится чтобы это включить, или где-то это сохранять. Также есть вероятность при добавлении нового вида критической секции забыть обновить обработчики прерываний на выключения для этого вида. Так что придерживаюсь своего мнения, что лучше перед секцией отключать конкретные прерывания а в конце их включать, потому что так включение и выключение находятся рядом что повышает надежность. Если я чего-то упустил, был бы благодарен примеру, не стеба ради, а чтобы стать лучше чем был вчера...
|
|
|
|
|
Apr 3 2014, 06:58
|
Знающий
   
Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163

|
Цитата SVS - это че? Это видимо имелось в виду программное прерывание. Правильнее его называть SWI. Цитата а чтобы стать лучше чем был вчера... Проще использовать мютексы и не городить сложных систем с критическими секциями и платформозависимой атомарностью. Не разделяю любви с неблокирующим алгоритмам - их очень трудно поддерживать и очень легко сломать.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|