Перейти к содержанию
    

Shared std::list между обычным кодом и обработчиком прерывания

Здравствуйте.

Имеется список 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, и ставлю его во всех сомнительных случаях. Буду благодарен, если подкинете литературу по теме.

Изменено пользователем harmaa

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если убрать volatile, то код компилируется. Подскажите пожалуйста, какие нужно предпринять дополнительные действия для "правильного" доступа к списку и из основного кода, и из прерывания. Я плохо представляю, когда нужен volatile, и ставлю его во всех сомнительных случаях. Буду благодарен, если подкинете литературу по теме.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Однако вопрос вы задали...

 

Для начала убираем 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;

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

dxp, andrewlekar

 

Спасибо за ответы, пока вам отвечал, кучу материалов перерыл :). На время модификации у меня прерывания блокируются. Я почитал доку к компилятору (компилятор для TI C6000) и выяснил, что блокировка прерываний выключает оптимизацию и может использоваться для создания критических секций. Поллинг тоже собираюсь использовать для части операций.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...