Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Shared std::list между обычным кодом и обработчиком прерывания
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
harmaa
Здравствуйте.
Имеется список std::list<>
Код
  typedef std::list<TTransfer> TTransferQueue;
  volatile TTransferQueue mTransfers;

, в который могут добавляться и удаляться элементы из основного кода, и обработчик прерывания, который только читает элементы. Обычно таким переменным я ставлю volatile, но в этом случае компилятор ругается:

Код
error #1163: no instance of overloaded function
          "std::list<_Ty, _Ax>::end [with _Ty=TI2CController::TTransfer,
          _Ax=std::allocator<TI2CController::TTransfer>]" matches the argument
          list and object (the object has cv-qualifiers that prevent a match)
            object type is: volatile TI2CController::TTransferQueue
    : mNo(no), mBaseAddr(baseAddr), mTransfers(), mActiveTransfer(mTransfers.end()),
                                                                             ^


Если убрать volatile, то код компилируется. Подскажите пожалуйста, какие нужно предпринять дополнительные действия для "правильного" доступа к списку и из основного кода, и из прерывания. Я плохо представляю, когда нужен volatile, и ставлю его во всех сомнительных случаях. Буду благодарен, если подкинете литературу по теме.
dxp
QUOTE (harmaa @ Jul 17 2014, 18:07) *
Если убрать volatile, то код компилируется. Подскажите пожалуйста, какие нужно предпринять дополнительные действия для "правильного" доступа к списку и из основного кода, и из прерывания. Я плохо представляю, когда нужен volatile, и ставлю его во всех сомнительных случаях. Буду благодарен, если подкинете литературу по теме.

volatile нужен всегда, когда есть асинхронное изменение объекта. Если вы в прерывании не меняете состояние объекта, то volatile не нужен. А вот помимо volatile вам обязательно нужно защищать доступ в основной программе от асинхронного доступа (прерывания) к этому объекту - сделать доступ атомарным. Например, с помощью запрещения этого прерывания на время работы с объектом.
andrewlekar
Однако вопрос вы задали...

Для начала убираем volatile. Для таких структур от него толку мало будет.
Потом делаем переменные:
Код
volatile bool busy_from_int, busy_from_main;

В обработчике прерывания делаем так:
Код
if(busy_from_main) return;
busy_from_int = true;
mTransfers.read();
busy_from_int = false;

В приложении делаем так:
Код
if(busy_from_int) continue;
ENTER_CRITICAL();
if(busy_from_int) { EXIT_CRITICAL(); continue; }
busy_from_main = true;
EXIT_CRITICAL();
mTransfers.write();
busy_from_main = false;


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

Спасибо за ответы, пока вам отвечал, кучу материалов перерыл sm.gif. На время модификации у меня прерывания блокируются. Я почитал доку к компилятору (компилятор для TI C6000) и выяснил, что блокировка прерываний выключает оптимизацию и может использоваться для создания критических секций. Поллинг тоже собираюсь использовать для части операций.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.