Ну вообще-то это стандартный подход к написанию обработчиков прерываний.
Я бы скорее сказал не "стандартный", а "более корректный". Я удивлюсь, если окажется, что хотя бы один из десяти разработчиков встроенных программ пишет именно так.
ILYAUL писал(а):
Это Вы давненько с asm не работали, портировать его с платформы на платформу не так уж и сложно. Главное правильно сразу написать макросы.
То есть Керниган и Ритчи потратили время на разработку достаточно хорошо портируемого языка впустую, не зная про макросы? И достаточно просто, скажем, перейти с CISC на RISC (или обратно) разной разрядности простым набором макросов?
_________________ Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет. J. Ganssle
Не гладко, но хотя бы реально при разумных трудозатратах. Кабы каждую машинную команду пришлось переносить, не видать бы нам сегодня UNIX'а и его наследников на всевозможном железе - почили бы в бозе вместе со своими монструозными непортабельными собратьями.
Впрочем, это нас уже немного в сторону высоких материй утянуло. Как насчет первоначального вопроса (о вложенных вызовах нереентерабельного обработчика и связанных с этим проблемах), прояснил ситуацию или не совсем?
_________________ Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет. J. Ganssle
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
конечно если обнулять переменную то можно и не одну милисекунду потерять.а если вычесть из большего чем 1000 тысячу, то ничего страшного не произойдет. ну конечно еще нужно учитывать,что прерывание может произойти между сравнением и действием, тогда конечно может произойти неправильное действие(с устаревшим результатом) в общем случае счетчик самих секунд можно добавлять и отнимать из милисекунд в основном цикле я так понимаю эту картину. а вообще в самом прерывании можно разрешить вложенные только после выполнения критической части,которая может вызвать такие казусы в процессе работы.
_________________ В поисках истины человек развивается.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Чтобы прерывания не испортили результат сравнения перед действием, флаги сохранить бы не плохо, по нормальному так и надо делать в обработчике прерывания, сохранять все используемые обработчиком регистры и обязательно флаговый регистр, тогда и думать лишний раз не придется, что прерывание чего-то там испортит.
а вообще в самом прерывании можно разрешить вложенные только после выполнения критической части,которая может вызвать такие казусы в процессе работы.
Правильно. Выделение критической секции кода и введение блокировки, которая позволяет лишь одному потоку управления одновременно находиться в критической секции (а временный запрет вложенных прерываний как раз и есть наиболее простая реализация такой блокировки при отсутствии объектов ядра ОС наподобие семафоров или мьютексов) делает подпрограмму обработки прерывания реентерабельной, так что к ней уже не относятся указанные проблемы.
Так что мы уже по второму кругу вышли на то, с чего и начинали: нельзя повторно входить в нереентерабельный обработчик. Нужно либо запрещать вложенность, либо делать обработчик реентерабельным (впрочем, в нашем случает это тоже достигается запретом прерываний, только не полным, а лишь на протяжении критической секции, которая модифицирует глобальные по отношению к обработчику переменные).
_________________ Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет. J. Ganssle
по нормальному так и надо делать в обработчике прерывания, сохранять все используемые обработчиком регистры и обязательно флаговый регистр
А разве получится как-то иначе? Я думал, это давно аксиома. Так же, как и обеспечение атомарного доступа к данным.
Цитата:
как раз и есть наиболее простая реализация такой блокировки при отсутствии объектов ядра ОС наподобие семафоров или мьютексов
Ну тут не стоит сравнивать, процессы (потоки) в многозадачной ОС - несколько другое. Каждый из них выполняется в отдельном контексте, и задача программиста лишь синхронизировать обмен данными между ними.
Чтобы прерывания не испортили результат сравнения перед действием, флаги сохранить бы не плохо, по нормальному так и надо делать в обработчике прерывания, сохранять все используемые обработчиком регистры и обязательно флаговый регистр, тогда и думать лишний раз не придется, что прерывание чего-то там испортит.
Проследите внимательнее последовательность действий в предложенном примере. Там вложенное прерывание происходит уже после того, как произошел условный переход, и флаги уже не имеют никакого значения. Сохранение флагов ничего не изменит в данной ситуации. А вообще сохранение контекста при входе в обработчик с последующим восстановлением перед выходом и без того должно делаться обязательно, иначе первое же прерывание обрушит фоновую программу, даже если не будет никакой вложенности.
_________________ Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет. J. Ganssle
Если по примеру, то получается каждый обработчик разрешает вложенное прерывание, так чтоли? Получается ведь снежный ком. А если, допустим, какой то конкретный обработчик будет разрешать только определенное вложенное прерывание, а остальные отключать до конца работы обработчика.
А разве получится как-то иначе? Я думал, это давно аксиома. Так же, как и обеспечение атомарного доступа к данным.
Более того, при использовании, например, GCC (другими не пользуюсь, поэтому не в курсе) нужно специально постараться, чтобы сохранение РОН и флагов не было сделано автоматически. Равно как и атомарность обработчика.
ploop писал(а):
процессы (потоки) в многозадачной ОС - несколько другое. Каждый из них выполняется в отдельном контексте...
От реализации модели потоков зависит. Например, в Protothreads, где кооперативная многопоточность реализована через сопрограммы, контекст вовсе отсутствует, а синхронизация все равно необходима (впрочем, это опять лежит далеко за пределами данной темы).
_________________ Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет. J. Ganssle
Именно так. Поэтому нужно очень крепко подумать, прежде чем решиться реализовать в своей системе вложенные прерывания (под вложенными я имею в виду повторно входящие в тот же обработчик до его завершения). Польза весьма сомнительна (если прерывания поступают быстрее, чем их успевают обрабатывать, и начинают укладываться в матрешку, все равно при таком подходе быстро исчерпается стек), а проблем, как мы уже видели, возникает масса.
_________________ Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет. J. Ganssle
А если, допустим, какой то конкретный обработчик будет разрешать только определенное вложенное прерывание, а остальные отключать до конца работы обработчика.
При такой тактике в принципе, можно поднять приоритет любому прерыванию, если обработчик прерывания с высшим приоритетом разрешит ему это, если например таймеру необходимо уложиться в срок, чтобы считать миллисекунды, мы впринципе тогда можем задать ему наивысший приоритет, даже выше чем INT0, скажем так, попросив любезнейший INT0 пропустить таймер вперед, все таки время не ждёт! , а остальные прерывания по боку, фейс контроль
При такой тактике в принципе, можно поднять приоритет любому прерыванию
Да, в принципе можно назначить всем прерываниям собственные приоритеты и написать подпрограмму, которая при входе в обработчик будет запрещать прерывания с приоритетом ниже текущего. Возможно, для каких-то задач это окажется действительно полезно.
Впрочем, правильно написанный обработчик будет иметь минимальную длину (и время выполнения). Вполне может оказаться, что он выполняется быстрее, чем наш планировщик приоритетов решает, какие прерывания включить, а какие выключить. Главное, чтобы накладные расходы не превысили выгоды от такой гибкой системы приоритетов. А то получится, что лекарство хуже болезни, которую оно должно лечить.
Ну и еще такое соображение: кристаллы начального уровня с плоской одноуровневой системой прерываний обычно решают простые задачи, где такое сложное планирование, скорее всего, будет избыточным. А более серьезные устройства поддерживают многоуровневую систему аппаратно, там такие ухищрения попросту не понадобятся.
_________________ Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет. J. Ganssle
Карма: 15
Рейтинг сообщений: 70
Зарегистрирован: Ср мар 28, 2012 21:45:24 Сообщений: 904 Откуда: ВО
Рейтинг сообщения:0
Я считаю , что при написании обработчиков прерываний , нужно исходить из конкретно поставленной задачи. Даже самому низшему аппаратному прерыванию можно сделать наивысший приоритет программно. Собтвенно прерывания высшего приоритета ( исходя из задачи) разрешены всегда и не требуют арбитража. Их обычно не много. Всегда можно отделить важное , от не очень - задача поставлена, приоритеты определены. Остальным можно написать арбитр. И вообще уйти в фоновый режим и обрабатывать младшие приоритеты не в основной программе , где опять могут действовать свои приоритеты. При этом вызов старших - прерывает фоновую задачу и проц может вообще "забыть" , что у него вообще существуют какие-то другие прерывания. При этом последующий возврат в фоновую задачу продолжится с прерванного места. Но тут уже "игрушки" со стеком.
хе можно немного увеличить приоритет другого прерывания методом проверки флага запроса нужного прерывания. сделать внутри другого прерывания добавку счетчика или другие действия, но опять же за счет увеличения нагрузки на ядро. выглядит это следующим образом: вместо разрешения прерываний 1.проверяем готовность флага 2.если необходимо, делаем вызов процедуры обработки флага. 3.сбрасываем флаг запроса прерывания. в меньшем случае три слова кода внутри прерывания если только инкремент 1байтной переменной сделать. а обработку в основном цикле. поправьте если не прав в расчете, в асме я плаваю.
_________________ В поисках истины человек развивается.
Большое спасибо Goldsmith за очень информативный ответ. На нашем курсе программирования МК в универе такое слово как реентерабельность даже не упоминалось, поэтому я сильно удивился, увидев незнакомый термин . Буду штудировать литературу. Только еще один вопрос конкретного характера: AVR'ки (простые, типа mega, tiny) при входе в прерывание сами блокируют перерывания и насколько (полностью, только того же типа...) и зависит ли это поведение от языка программирования (асм или Сишка)?
Флаг I (глобальный запрет прерываний) регистра SREG сбрасывается аппаратно при входе в прерывание, и устанавливается по команде RETI (по сути это RET + SEI ) . Так что тут не важно, какой язык.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения