Asm/C++/Delphi/Py/PHP/VBA
|
|
1 | |
Сброс бита регистра IRR контроллера прерываний 8259A08.09.2018, 22:21. Показов 2186. Ответов 13
Метки нет (Все метки)
Приветствую вас!
При появлении запроса на прерывание (IRQ) в регистре запросов прерывания IRR контроллера 8259A устанавливается бит, соответствующий этому прерыванию. Если бит регистра обслуживаемых запросов ISR того же прерывания (и всех более приоритетных) сброшен и прерывание незамаскировано (в IMR или через cli), процессор подтверждает прерывание и соответствующий бит в IRR сбрасывается, а в ISR устанавливается. После отправки команды EOI сбрасывается и бит регистра ISR, разрешая процессору снова прерывать выполнение кода вызовом обработчика того же прерывания (и менее приоритетных). Соответственно, поскольку после подтверждения прерывания процессором бит в IRR сбрасывается, он в любом момент может быть установлен снова, а значит, если мы ещё не завершили обработку прерывания, по после отправки EOI и выполнения iret/sti обработчик будет вызван снова. Мне необходимо предотвратить эту ситуацию и сбросить соответствующий бит регистра IRR перед выходом из обработчика прерывания (iret), ну или перед отправкой EOI. Вопрос: как это сделать? Регистр IRR можно без проблем прочитать, интерфейс для этого есть, а вот с записью проблема... Вот тут написано: Добавлено через 1 минуту Вариант инициализации контроллера прошу не предлагать
0
|
08.09.2018, 22:21 | |
Ответы с готовыми решениями:
13
Сброс бита n Сброс бита CBI (Atmel Studio 6.2) Контроллер прерываний и маскирование ведомого контроллера Понимание работы контроллера вложенных прерываний |
6770 / 2739 / 384
Регистрация: 17.02.2013
Сообщений: 4,048
|
|
08.09.2018, 23:47 | 2 |
Имеется ввиду внешним устройством снимается.
Программно и прямо никак. IRQ - это сигнал на шине от внешнего устройства. И внешнее устройство хочет, этот сигнал выставляет, не хочет не выставляет. На выставление этого сигнала внешним устройством можно влиять только косвенно, при обработке прерывания как-то его ублажив.
По моему в том абзаце, что ты процитировал, тот кто его писал сам не понимал, что писал. Если выставление сигнала IRQ защелкивается в каком-то триггере внутри 8259A, то после размаскирования прерывание должно произойти, неважно выставлен ли сигнал IRQ к этому моменту или уже был снят. А если выставление сигнала IRQ не защелкивается, то какой тогда смысл писать Когда возникает запрос на прерывание, который замаскирован разрядом в IMR, он не теряется когда при снятии сигнала IRQ он именно-что теряется. В общем надо найти более вменяемое описание. Добавлено через 11 минут З.Ы. У Искры-1030.11 был не RS-232, а Стык-С2. Когда-то я самодельную схему нарисовал, мой друг развел плату RS-232 для Искры и спаял и мы подключали по ночам Искру через модем к Униксовому серверу на моей работе. Так вот когда мы это делали, я так и не понял как по уму прерывания должны работать. Наша плата идеально работала в режиме опроса готовности и фидошным софтом мы почту принимали и терминалом telnet-ом на серверок заходили. Но стоило попробовать любой софт, что работал с RS-232 по прерываниям, как стоило только одному прерыванию произойти, тут они и начинали валить бесконечно. Масла в огонь подливало то, что у Искры была совсем другая шина, чем у ПК и спецификации на Искровскую шину мы не имели. Только схему самой Искры и по ней только догадывались как должно работать. У ПК-то шина синхронная, а у Искры была асинхронная. Так вот тогда я так и не понял как работает сигнал IRQ - фронтом или уровнем. Получалось по факту, что уровнем и в результает выходила полная херь с бесконечными прерываниями. Но вот как оно должно было работать на самом деле и как мне переделать схему я так и не понял. И вот у тебя теперь похожая фигня. Есть какие-то описания, но тот кто их писал, делал это явно в невменяемом состоянии. Ну или смотрел на это дело как программист, который как оно работает электрически просто не задумывается. И в итоге от этих описаний все равно остается непонятка. Добавлено через 2 минуты З.З.Ы. Во чего нашел Помимо собственно инициализации контроллеров, необходимо указать, какие линии IRQ будут обслуживаться по уровню сигнала, а какие — по его фронту. Это осуществляется записью нужных значений в регистры ELCR (порты 4D0h и 4D1h для ведущего и ведомого контроллеров соответственно). Пять линий — IRQ0, IRQ1, IRQ2, IRQ8 и IRQ13 — всегда программируются на реакцию по фронту сигнала; соответствующие им биты регистров ELCR должны быть равны нулю. Остальные линии могут программироваться на реакцию как по фронту, так и по уровню. Видимо на этом я когда-то и накололся. Хотя нет, а откуда на Искре порты > 3FFh ? Ну так в любом случае тебе надо выставить обработку IRQ по фронту. Тогда тем-же уровнем IRQ никакой бит IRR заново выставляться не будет. А вот если внешнее устройство быстренько пошлет два фронта подряд, вот этого ты уже никак не победишь. Раз запросы на прерывание были, так будь добр обработать. Добавлено через 6 минут Или в обработчике прерывания маскируй прерывания и через некоторое время эту маску снимай. В любом случае ты не объяснил зачем собираешься нарушить логику работы прерываний ? Ведь ты собираешься некоторые запросы на прерывание тупо пропускать. Зачем делать криво, если было прямо ?
1
|
1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266
|
|
09.09.2018, 01:56 | 3 |
Ethereal, более понятно объясняю:
1) всё, что приходит в 8259, защёлкивается в IRR, всегда, аппаратно, вне зависимости от состояния IMR 2) как только возникает возможность обработать прерывание, этот бит из IRR кочует в ISR, что означает "прерывание в процессе" 3) Jin X обрабатывает прерывания довольно долго и существует риск, что в это время в IRR асинхронно ещё чего-нибудь защёлкнется, и сразу же по выходу из обработчика опять уйдёт на вот это прерывание, которое было "в очереди", но "просрочилось" и уже не нужно 4) ему надо каким-либо образом отменить пункт 2, сбросив IRR перед выходом из первого прерывания, чтобы второе сразу же не возникло 5) документация по этому вопросу очень слабая, не очень внятно описан даже алгоритм отклонения запросов контроллером 8259, про возможность сброса IRR не написано вообще ничего, кроме одной фразы одного чувака с WASM, что якобы определённая комбинация бит в одной из управляющих команд позволяет это сделать (не знаю, проверял ли этот способ Jin X).
1
|
6770 / 2739 / 384
Регистрация: 17.02.2013
Сообщений: 4,048
|
|
09.09.2018, 02:29 | 4 |
Ты бы вместо того чтобы объяснять вопрос одного человека другому человеку, на сам вопрос-бы ответил. Добровольный помошник, блин.
Ну так я-же сказал перевести контроллер прерываний для данной линии IRQ в режим работы по фронту. Тогда в IRR ничего не защелкнется асинхронно.
1
|
1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266
|
|
09.09.2018, 03:01 | 5 |
Он ловит IRQ 0 от таймера, который и так уже в режиме прерывания по фронту.
Интересно вот, что будет, если его наоборот перевести в режим прерывания по уровню???
1
|
6770 / 2739 / 384
Регистрация: 17.02.2013
Сообщений: 4,048
|
|
09.09.2018, 08:34 | 6 |
Блин, сорри, вспылил. Но уж в очень неудачной форме был твой пост.
Добавлено через 9 минут Блин. Ну вот можно было бы об этом и сразу сказать. Значится хочет ловить прерывания от таймера и хочет задержаться в нем подольше и наверное всякие видеоэффекты рисовать. А тем временем таймер может еще раз тикнуть и еще раз. И надо защелкнутый запрос на прерывание помножить на ноль. Ну не видать нигде в описаниях этой чипы даже намека, что так программно можно сделать. Недокументированная возмозмость такого может быть, конечно. Но тут придется контроллер прерываний всеми возможными сочетаниями бит в управляющих командах высношать, пока это найти. Добавлено через 6 минут В том-то и дело. В своем длинном посту в самом верху я написал одну неправильную вещь, глянул в PDF и неправильность стала ясна. Но недоумение-то все равно осталось. Я не понимаю как контроллер прерываний может работать по уровню. Или выставление этого уровня должно быть минимально короткое - длиной в один такт на шине или неизбежен обвал повторных прерываний, ну прям как тогда у меня на Искре. Вот от уровня IRQ выставился бит в IRR. Вот пошло прерывание. Бит в IRR сбросился, выставился в ISR. Но если идет работа по уровню и IRQ все еще стоит, то IRR тут-же снова выставится и повторное прерывание сразу после обработки первого неизбежно. Если IRQ продолжает стоять, то будет и третье прерывание и четвертое. IRQ 0 небось работает по фронту именно потому, что на эту линию наверно тупо поступает частота кварца 14.3 Mhz деленная на 12, а не кратчайшие импульсы. Добавлено через 44 минуты Идея : А вообще, почему бы у таймера в начале обработчика прерывания не изменить значение самого старшего бита старшего байта так, чтобы до конца работы обработчика таймер не переполнился, а перед выходом из обработчика откорректировать бит обратно. Тогда регистр IRR во время работы обработчика выставляться не будет. Переполнение таймера ведь при полном диапазоне 0..FFFF 18.2 Гц, а частота кадровой развертки изображения более чем в 3 раза больше. Т.е самый старший бит переворачивать можно безболезненно. Я так понимаю, что если происходит прерывание по переполнению таймера, то на входе в обработчик до момента инкремента старшего байта еще далеко и можно не глядя корректировать. Надо подумать как не нарваться корректировкой на момент инкремента старшего байта на выходе из обработчика. Ну чтобы случайно не потерять 256 тиков.
1
|
Asm/C++/Delphi/Py/PHP/VBA
|
|
09.09.2018, 08:38 [ТС] | 7 |
Эта тема относится к Номер текущей строки CRT-луча
Там да, как раз IRQ 0. И его перенести на "уровень" нельзя, он всегда работает по фронту (хотя я, честно говоря, не совсем понимаю разницы). IRQ 0 может обрабатываться долго только в начале кадра (я даже уверен, что он пару IRQ-запросов "проглотит"). В общем-то, я придумал, как эту проблему решить. Там счётчик программно настраивается, так вот можно в самом начале этой "долгой обработки" выставить счётчик на максимум (0=65536), 55 мс хватит с лихвой (там и 1 мс хватит, но изначально таймер настроен на ≈ 30 кГц... да, да, вот такие скорости). Эта комбинация (если она, конечно, работает) сбрасывает все биты. Т.е. если я, к примеру, нажму какую-то клавишу во время обработки прерывания, она просто можно не сработать. Добавлено через 2 минуты Опередил Да, я примерно так и хочу сделать Только там нельзя отдельный бит выставить, там сразу всё число записывается, так что пишем 0 и всё. Всё равно таймер каждый раз перенастраиваться (перезапускаться) будет.
1
|
6770 / 2739 / 384
Регистрация: 17.02.2013
Сообщений: 4,048
|
|
09.09.2018, 08:40 | 8 |
1
|
Asm/C++/Delphi/Py/PHP/VBA
|
|
09.09.2018, 08:40 [ТС] | 9 |
Кстати, раз уж речь об этом зашла. Если мы пишем не 2 байта в счётчик, а один (старший или младший), что происходит со вторым байтом? Т.е. было, скажем, 1234h. Если мы изменили 12h на 21h, то 34h не изменится или сбросится в 0? Ну и наоборот: если поменяли 34h на 56h, что будет с 12h? Надо бы протестить...
1
|
6770 / 2739 / 384
Регистрация: 17.02.2013
Сообщений: 4,048
|
|
09.09.2018, 08:43 | 10 |
Вот если бы ты это в начале темы написал, то решение быстрее бы нашлось. Чем решать абстрактную задачу гораздо легче использовать особенности конкретной
Тут надо потестить. А то теоретически может казаться что произойдет одно, а на практике ... надо посмотреть.
1
|
Asm/C++/Delphi/Py/PHP/VBA
|
|
09.09.2018, 13:10 [ТС] | 11 |
И я так понимаю, тактовый генератор 1.19 МГц работает всегда в своём темпе, без перезапуска? Т.е. если я записал в счётчик какие-то число, он же (генератор) не перезапускается в этот момент, а продолжает работать (перезаписывается только значение счётчика).
Схематично (1 строка с частотой 1.19*4 МГц) значения счётчика: 100 100 100 100 99 99 99 99 98 98 тут я записал в счётчик 200, далее будет: 199 199 198 198 а не: 199 199 199 199 198 198 ... ??? Добавлено через 4 часа 18 минут Потестил. Очень забавно всё работает. Во-первых, при любом раскладе, если записываем 1 байт (только младший или старший), то изначально в счётчик заносится 2 одинаковых байта (на ноуте при записи в младший байт в старший заносится значение на 4 меньше, чем в младший, в DOSBox или при записи в старший такого нет). Далее... Если пишем только младший байт, счётчик уменьшается по 101h на каждый тик: Кликните здесь для просмотра всего текста
48576
47291 45750 44465 43180 41895 40610 39324 38039 36754 35469 34184 32899 31614 30329 29044 27759 26474 25189 23648 22363 21078 19793 18508 17222 15937 14652 13367 12082 10797 9512 8227 6942 5657 4372 3087 1802 261 48320 47035 45749 44464 43179 41894 40609 39324 38039 36754 Если пишем только старший байт, счётчик уменьшается тоже по 101h, но не на каждый тик, а раз в... (101h тиков?) Кликните здесь для просмотра всего текста
49088
49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 49087 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48830 48574 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 48573 Причём, забавный факт (если вы заметили в спойлерах): на первый раз значение иногда больше на 1, чем в последующий (в DOSBox такого нет). Это всё для режима 2. Для режима 3 числа меняются в 2 раза быстрее (что, в общем-то, неудивительно) и разница не 4, а 8. И ещё прикол: делаю последовательное чтение в цикле в буфер с включенным cli (прога под DOS на паскале). Запускаю на ноуте, получаю значение раз в 5 циклов (почти ровно). Кликните здесь для просмотра всего текста
4659
4654 4649 4644 4639 4634 4629 4624 4619 4614 4609 4604 4599 4594 4589 4584 4579 4574 4568 4563 4558 4553 4548 4543 4538 4533 4528 4523 4518 4513 4508 4503 4498 4493 4488 4482 4477 4472 4467 4462 4457 4452 4447 4442 4437 4432 4427 4422 Почему так медленно, кто-нибудь знает???
1
|
ФедосеевПавел
|
09.09.2018, 17:29
#12
|
Не по теме: Ethereal, я работал с "Искра 1030М". Она комплектовалась платой расширения ААПД с несколькими ИРПС и одним Стык-С2 (он же RS-232).
0
|
6770 / 2739 / 384
Регистрация: 17.02.2013
Сообщений: 4,048
|
|
12.09.2018, 05:08 | 13 |
Ты не понял. В моем случае в Искру была воткнута моей разработки плата и в ней стояла вполне себе i8250 совместимая микросхема. Кажется 16C450, но уже не помню точно. Я только тогда неудачно прикрутил к шине Искры прерывания от этой микросхемы.
Не в этом дело. Каждое изменение таймера происходит в момент прихода фронта клока, который получается делением частоты кварца на 12. На этот клок ты не можешь повлиять и сделать так, чтобы его фронты подстроились под моменты записи тобой в таймер новых значений.
В общем это не таймер не перезапускается, это клок, идущий на таймер не перезапускается, клочит и клочит сам по себе. Не обращая внимание на то, что ты в таймер в данный момент пишешь новое значение. Это вот в микроконтроллерах делается так, чтобы можно было программу с таймером синхронизировать абсолютно. Там каждый такт каждой исполняемой команды можно посчитать и каждый тик таймера, тикающего параллельно с исполнением команд посчитать и знать в момент исполнения какой конкретной команды таймер инкрементируется и какое значение при этом будет иметь. В ПК таких железных времянок нет. Тут уже главное чтобы работало не точно, а молотило программу быстрее. Конвейеры, кеши, шмеши и ничего точно уже не посчитаешь. Добавлено через 9 минут Не знаю в этом ли дело, но давным давно я обнаружил такую вещь. Не знаю справедливо ли это для современных ПК. Но тогда давно обнаружил такое - комп может быть иметь сколько угодно быстрый проц, но вот команды in и out насрамши на проц всегда будут исполняться около микросекунды. Поэтому я маленькие и стабильные задержки именно командами in и out делал. Может это было справедливо только для материнских плат с шиной ISA, не знаю, но может оказаться, что это и всегда так - in и out исполняются медленно, по времянкам шины, а не по тактовой частоте проца.
2
|
Asm/C++/Delphi/Py/PHP/VBA
|
|
12.09.2018, 09:36 [ТС] | 14 |
Я и подумал, что скорее всего так и будет. Но всё же решил спросить, мало ли...
Жесть, конечно. Ну вообще, я заметил, что и in из порта 3DAh тоже не так часто читает. Надо ещё не стационарном попробовать (то ноут был).
0
|
12.09.2018, 09:36 | |
12.09.2018, 09:36 | |
Помогаю со студенческими работами здесь
14
Преобразовать 2 регистра 16 бит в 32 бита float Переписать три младших бита регистра ВХ на место 10,11 и 12 битов Сброс контроллера при появлении внешнего питания Как обнулить три старших бита регистра DH, без изменения остальных бит Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |