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

 
 
> Критические секции
jorikdima
сообщение Aug 10 2009, 10:44
Сообщение #1


тут может быть ваша реклама
*****

Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280



Добрый день.
Есть следующий вопрос при использовании ОС для MSP430, зотя ни ОС, ни uC в данном случае роли не играют.
У меня используется ДМА и по завершении работы канала ДМА случается прерывание, которое в свою очередь сигнализирует флагом, говоря, что ДМА окончило работу. И есть предположим для простоты один только процесс. В этом процессе происходит инициализация и зарядка ДМА. ДМА шлет в порт, поэтому насколько я понимаю это может длиться долго, настолько долго, что можно поделать какую-либо работу пока ДМА трудится. Но потом (предположим все в рамках одного процесса) наступает момент в коде, когда мне обязательно надо дождаться окончание той пересылки, которую выполняет ДМА . Структурно все это выглядит так:
Код
InitDMA();
StartDMA();

//*************
SOME CODE
// ************

DMAFlag.Wait();


Так как мне нужно дождаться окончания персылки, то я для сигнализации использую флаг. А именно, всем кому нужно узнать о завершении транзакции просто пишут DMAFlag.Wait(); Как только ДМА освободится, он всем просигналит. Но проблема в том, что просто использовать DMAFlag.Wait(); нельзя, потому что в этот момент ДМА может быть уже свободен, сооветственно в случае одного процесса вообще навсегда зависнем, потому что ДМА никто не зарядит и флаг больше никогда никем не взведется. Поэтому надо сначала проверить, а не занят ли он (хоть даже по битику DMAEN, неважно), а затем в случае занятости ждать флага. Но эти две операции не атомарные и их надо заключить в критическую секцию по идее. Потому что может быть так, что мы проверим битик DMAEN , увидим что он занят, а сразу после этого произойдет прерывание, в котором установится флаг. Потом прерывание окончится, а мы пойдем ждать флага, бесконечно. Но... как же я могу в критической секции, которая запрещает прерывания вызывать Wait() для флага. Ведь я там в любом случае бесконечно останусь с запретом то прерываний.
Как делают опытные в таких случаях?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 2)
Сергей Борщ
сообщение Aug 10 2009, 11:12
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(jorikdima @ Aug 10 2009, 13:44) *
Но... как же я могу в критической секции, которая запрещает прерывания вызывать Wait() для флага. Ведь я там в любом случае бесконечно останусь с запретом то прерываний.
Посмотрите исходник любого сервиса, в том числе и TEventFlag::Wait(). Он начинается с критической секции. Если Wait() требуется ожидание, то присходит передача управления другому процессу (в крайнем случае процессу Idle), а уже в этом процессе прерывания разрешены.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
jorikdima
сообщение Aug 11 2009, 16:37
Сообщение #3


тут может быть ваша реклама
*****

Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280



То есть это безопасно. Спасибо!
Go to the top of the page
 
+Quote Post

Closed TopicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 14:41
Рейтинг@Mail.ru


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