harmaa 0 17 июля, 2014 Опубликовано 17 июля, 2014 (изменено) · Жалоба Здравствуйте. Имеется список 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, и ставлю его во всех сомнительных случаях. Буду благодарен, если подкинете литературу по теме. Изменено 17 июля, 2014 пользователем harmaa Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 34 18 июля, 2014 Опубликовано 18 июля, 2014 · Жалоба Если убрать volatile, то код компилируется. Подскажите пожалуйста, какие нужно предпринять дополнительные действия для "правильного" доступа к списку и из основного кода, и из прерывания. Я плохо представляю, когда нужен volatile, и ставлю его во всех сомнительных случаях. Буду благодарен, если подкинете литературу по теме. volatile нужен всегда, когда есть асинхронное изменение объекта. Если вы в прерывании не меняете состояние объекта, то volatile не нужен. А вот помимо volatile вам обязательно нужно защищать доступ в основной программе от асинхронного доступа (прерывания) к этому объекту - сделать доступ атомарным. Например, с помощью запрещения этого прерывания на время работы с объектом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrewlekar 0 18 июля, 2014 Опубликовано 18 июля, 2014 · Жалоба Однако вопрос вы задали... Для начала убираем 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 0 18 июля, 2014 Опубликовано 18 июля, 2014 · Жалоба dxp, andrewlekar Спасибо за ответы, пока вам отвечал, кучу материалов перерыл :). На время модификации у меня прерывания блокируются. Я почитал доку к компилятору (компилятор для TI C6000) и выяснил, что блокировка прерываний выключает оптимизацию и может использоваться для создания критических секций. Поллинг тоже собираюсь использовать для части операций. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться