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

Проблема LPC2214 UART+T0 IRQ

Если точка останова на irq_handler то постоянно вылезают DummyInterrupt.

У меня такая же фигня, это наверно то что описано в SPURIOUS INTERRUPTS :blink:

Попробуйте в окне регистров выбрать что-нибудь отличное от VIC. Или в .ddf уберите из описания этого окна VicVectAddr. Дело в том что чтение этого регистра (отладчиком) дает сигнал к загрузке в него след. значения.

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


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

Если вы всетаки взгляните на код в начале ветки, то увидите что прерывание на контроллере сбрасывалось

Виноват :-(, хотя лишнего там много, отформатировать не сочли нужным и код с разными 0x01 вместо поименованных констант тоже не способствует желанию читать.

Посмотрел. Все вышесказанное относится и к парочке IIR RBR. Вычитывание FIFO c отражением сего факта в LSR

не должно приводить с сбросу запроса прерывания равно как и сброс прерывания не должен приводить :-) к сбросу содержимого FIFO

Для полного счастья нужно и вычитать FIFO и считать IIR. Операции отдельные ибо я имею право читать FIFO когда и где мне заблагорассудится и это не должно приводить к "ичезновению" флага причины прерывния в IIR наоборот - считать IIR и решив, что мне сейчас не до этого - уйти не вычитывая FIFO.

 

Сие абослютно логично и описано в документации.

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


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

Для полного счастья нужно и вычитать FIFO и считать IIR.

....

Сие абослютно логично и описано в документации.

Простите, но смотрю в таблицу #81 UART0 Interrupt Handling мануала по 2214, нахожу нужные мне две строчки для IIR=0100 и 1100 (данные доступны и таймаут по приему), смотрю на заветную колонку INTERRUPT RESET, там черным по англицки написано U0RBR READ, и ни слова что нужно читать IIR. А выходит что не читая IIR а обходясь только LSR и RBR прерывание не сбрасывается, в докции в самом начале описания обработки прерывания прямо в тексте мелким шрифтом есть что-то похожее на то что надо IIR всеже надо прочитать до выхода из обработчика.

 

А насчет дефайнов - сорри, я код причесывал специально чтобы поменьше в ветку вываливать текста, кроме того я тег не поставил чтобы форматироание сохранилось :) все время забываю какой он.

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


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

...там черным по англицки написано U0RBR READ, и ни слова что нужно читать IIR.

А выходит что не читая IIR а обходясь только LSR и RBR прерывание не сбрасывается,

в докции в самом начале описания обработки прерывания прямо в тексте мелким шрифтом есть что-то похожее на то что надо IIR всеже надо прочитать до выхода из обработчика.

Да нормальный там шрифт :-) и написано вполне "в лоб":

Interrupts are handled as described in Table 9–105. Given the status of U0IIR[3:0], an
interrupt handler routine can determine the cause of the interrupt and how to clear the
active interrupt. The U0IIR must be read in order to clear the interrupt prior to exiting the
Interrupt Service Routine.

Ну а самое главное, к чему я собственно "привязался" это то, что такое поведение является правильным, логичным и привычным для железок которые позволяют реализовывать идеи "посложнее".

 

Еще результаты чтения:

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

Ну и размещения кода в RAM не слишком уж ускоряет - MAM у LPC неплохой, зато чрезмерное увлечение подпрограммами уж точно тормозит.

 

 

 

По-моему, описанная проблема - не вызывается обработчик прерывания - очень плохо вяжется с "проблемами со стеком".

Прочитайте - там не "не вызывается" там:

Через какое-то время перестают вызываться обработчики прерываний,

И я говорил о статистике, голой статистике - ввиду отсутствия информации к размышлению.

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


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

Еще результаты чтения:

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

Это понятно, но ресурсов хватает выше крыши, а так СИ код прозрачен и понятен, врубать же ассемблерные куски лишние хлопоты. Я когда то давно спрашивал как это можно изящно изобразить на СИ, других вариантов не подсказали.

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


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

Это понятно, но ресурсов хватает выше крыши, а так СИ код прозрачен и понятен, врубать же ассемблерные куски лишние хлопоты.

A Вы свой cstartup.s79 тоже для ясности на "C" :-). Так вот - замените там одну "непонятную" строчку на другую и все.

Я когда то давно спрашивал как это можно изящно изобразить на СИ, других вариантов не подсказали.

Даже на "C" изящность уж приведенный в первом посте код не тянет уж совсем :-(. Не говоря уже о соревновании в изяществе с ОДНОЙ строчкой на ASM.

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


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

Так вот - замените там одну "непонятную" строчку на другую и все.

А как выковырнуть из проекта "свой" стартап?

Со стартапом из ../lib естественно не прокатывает, там не стартап а сплошной комментарий.

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


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

Со стартапом из ../lib естественно не прокатывает, там не стартап а сплошной комментарий.

Не "выковырнуть" а положить свой, сделанный, из того-же самого библиотечного. Благо комментариев там много :-).

Если "мало" - в приложении моя болванка. Посеченная до почти полного минимализма - самое то для начала.

CSTARTUP.rar

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

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


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

Если "мало" - в приложении моя болванка. Посеченная до почти полного минимализма - самое то для начала.

В каком приложении?

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


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

А почемуб по честному не читать IRR и в соответствии с причиной прерывания действовать, дабы это прерывание сбрасывалось.

Это не честнее, это просто еще более громоздко. Нормальный подход это ОДНА команда:

 

                ldr     pc,[pc,#-0xFF0]    ; 18 Jump directly to the address given by the AIC
                                              ; from [0xFFFFF020] Curent 18h +8(conveyer)=20h

 

А всётаки IRR в обработчике прерывания UART читать надо :)

А если прерывания все кроме приёма отключены, это не значит что не надо обрабатывать другие ситуации типа RX Line status Error, что кстати тоже зачастую лучше далать в прерывании.

 

Ну а про общий обработчик IRQ прерывания, тут уж что кому нравится

Стартап CW автоматом генерит

ldr     pc,[pc,#-0xFF0]

если определён VECTORED_IRQ_INTERRUPTS (и я этим пользуюсь).

Но тут надо помнить что запись в VICVectAddr нужна в каждом обработчике.

 

Но и общий обработчик IRQ в ряде случаев полезен, например в ОС-ах и т.д., проблема у автора треда не в нём была. :)

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


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

А всётаки IRR в обработчике прерывания UART читать надо :)

Я утверждал обратное про обработчик прерывания UART а не про общий обработчик???

А если прерывания все кроме приёма отключены, это не значит что не надо обрабатывать другие ситуации типа RX Line status Error, что кстати тоже зачастую лучше далать в прерывании.

А вот если 'отключены', то в IIR (полагаю речь идет о нем а не о каком-то IRR) их не будет и быть не

может.

Но тут надо помнить что запись в VICVectAddr нужна в каждом обработчике.

Жуткий напряг и нагрузка на память программиста :-)

Но и общий обработчик IRQ в ряде случаев полезен, например в ОС-ах и т.д.,

А вот с этого места, пожалуйста поподробнее. Очень люблю про OSы думать. Заинтриговали.

проблема у автора треда не в нём была. :)

А я сие и не утверждал - речь была просто о уменьшении количества выставленного на обозрение кода.

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


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

Но и общий обработчик IRQ в ряде случаев полезен, например в ОС-ах и т.д.,

А вот с этого места, пожалуйста поподробнее. Очень люблю про OSы думать. Заинтриговали.

 

Если Вам надо выполнять одно и то-же действие перед и/или после любого из прерываний.

Например:

- Подсчёт статистики, такой как кол-во прерываний, систем_тайм/юзер_тайм и т.д.

- Переключение задач по соответствующим условиям, как то с низкоприоритетной прерванной задачи, на более (сильно/реалтайм) приоритетную, которая была выведена из спячки текущим прерыванием.

- Разрешение вложенных прерываний, опять же в соответствии с заданной в ОС логикой.

 

Также в ОС-ах бывает вызов нескольких зерегестрированных обработчиков по списку, как пример, в PC архитектуре когда на одном физическом прерывании может несколько девайсов висеть, и когда драйвера, а с ними и обработчики прерываний, являются динамически загружаемыми/выгружаемыми модулями.

 

Ну и как доп. уровень абстракции когда писатель драйвера конкретной железки, не занимается программированием MMU или там контроллера прерываний (как то запись в VICVectAddr :) ), а использует допустимые (документированные) для данной ОС механизмы.

 

и т.д. зависит от ОС, от архитектуры и прочего.

Чем навороченнее ОС тем больше вариантов.

Я ОС-ем пока не писал. :)

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


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

Если Вам надо выполнять одно и то-же действие перед и/или после любого из прерываний.

Хорошо, посмотрим, что предлагается:

- Подсчёт статистики, такой как кол-во прерываний,

Сильно. Просто общее количество прерываний и за каждое обработанное прерывание брать денюжку :-), хотя опять некоторые сложно обрабатывать а некоторве попроще. Тогда надо считать их отдельно, тогда зачем общий обработчик?

систем_тайм/юзер_тайм и т.д.

А это уже конкретные обработчики, ну право-же не считать-же системное время по сумме прерываний от таймера, мышки и клавиатуры.

- Переключение задач по соответствующим условиям, как то с низкоприоритетной прерванной задачи, на более (сильно/реалтайм) приоритетную, которая была выведена из спячки текущим прерыванием.

Действия понятны, но с этим разбирается система а не какой-то универсальный пролог/эпилог ко всем прерываниям.

- Разрешение вложенных прерываний, опять же в соответствии с заданной в ОС логикой.

Разрешение вложенных прерываний огульно любого в любом. Выделение, например стека, неведомого размера (или наоборот не выделение) под вложенное. Причем до того, когда когда управление

получит обработчик конкретного прерывания или таже OS. При этом не запущенный обработчик

прерывания той-же OS как-то "задает логику"? Вот когда он получит управление он и будет "задавать логику" и именно он а не прокладка перед ним.

в PC архитектуре когда на одном физическом прерывании может несколько девайсов висеть

Это к архитектуре никакого отнощения не имеет, у меня вот прямо сейчас перед носом 16 на одном

прерывании висят. И разбирается кто вылез обработчик конкретного прерывания, который знает

как разобраться "кто сказал Гав" а не некая абстрактная прокладка для всех прерываний вместе взятых.

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

Сильно. Т.е. девайса нет (не вставили), драйвера нет(не загрузили) а обработчик прерывания - вот он уже есть и готов работать с неведомым ему железом на неведомом прерывании.

Ну и как доп. уровень абстракции когда писатель драйвера конкретной железки, не занимается программированием MMU или там контроллера прерываний (как то запись в VICVectAddr :) ), а использует допустимые (документированные) для данной ОС механизмы.

Живые примеры вышеописанного "ненавязчивого сервиса" имеют место быть, только зачем для этого обязательно иметь некую абстрактную прокладку перед или после собственно обработчика прерывания, который будет писать писатель драйвера?

Чем навороченнее ОС тем больше вариантов.

Навернуть можно много чего, вопрос зачем?

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

захочу разрешить в одном (только упаси боже не во всех зараз) обработчике вложенные прерывания?

Нафига мне тогда такой сервис?

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


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

Уважаемый zltigo!

У меня нет желания спорить с Вами.

Я лишь привёл несколько примеров, причём далеко на всех.

 

- Подсчёт статистики, такой как кол-во прерываний,

Сильно. Просто общее количество прерываний и за каждое обработанное прерывание брать денюжку :-), хотя опять некоторые сложно обрабатывать а некоторве попроще. Тогда надо считать их отдельно, тогда зачем общий обработчик?

 

Ну почему же общее, считать по конкретному прерыванию.

Общий обработчик конечно же должен знать, скажем так, индекс прерывания.

Например в нашей ОС возможно максимум N источников прерываний.

Тогда имея

nIntCounts[N] - массив счётчиков по всем перрываниям

pIntFn[N] - массив указателей на зарегистрированные обработчики

В общем обработчике можно например так:

    nIntCounts[nIntIdx]++;
    if(pIntFn[nIntIdx])
        pIntFn[nIntIdx]();

Откуда взять индекс? Зависит от архитектуры, но на примере того же LPC - а кто Вам сказал что в VicVectAddr/VicVectAddrX должен лежать именно адрес? Туда можно этот индекс и положить. :)

 

Наберите в Linux-е командочку

# cat /proc/interrupts

Притом если процев/ядер в системе несколько, то прерывания ещё и по каждому процу отдельно считаются.

 

систем_тайм/юзер_тайм и т.д.

А это уже конкретные обработчики, ну право-же не считать-же системное время по сумме прерываний от таймера, мышки и клавиатуры.

Не по сумме прерываний, а по сумме времени затраченного на исполнение прерываний, процессов ядра и юзерских процессов.

В роли таймера тут могут быть как некий системный таймер, так и какойнить счётчик тактов который например присутствует во всех современных пнях (и прочих x86).

 

 

- Переключение задач по соответствующим условиям, как то с низкоприоритетной прерванной задачи, на более (сильно/реалтайм) приоритетную, которая была выведена из спячки текущим прерыванием.

Действия понятны, но с этим разбирается система а не какой-то универсальный пролог/эпилог ко всем прерываниям.

 

И где по Вашему этим система разбирается?

1. Исполняется юзер-процесс

2. Происходит прерывание

3. Исполняется Ваш обработчик, который выводит из спячки высокоприоритетный процесс.

4. Возврат из прерывания

5. ??? Опять юзер-процесс ??? Где переключение контекста на высокоприоритетный процесс?

 

- Разрешение вложенных прерываний, опять же в соответствии с заданной в ОС логикой.

Разрешение вложенных прерываний огульно любого в любом. Выделение, например стека, неведомого размера (или наоборот не выделение) под вложенное. Причем до того, когда когда управление

получит обработчик конкретного прерывания или таже OS. При этом не запущенный обработчик

прерывания той-же OS как-то "задает логику"? Вот когда он получит управление он и будет "задавать логику" и именно он а не прокладка перед ним.

 

Ну почему же любого в любом?

Рядом с упомянутыми массивами nIntCounts[N], pIntFn[N] положите ещё массив с флагами для каждого прерывания, такими как возможность разрешения вложенности, флаг реентерабельности (повторного вхождения) и т.д.

 

Вариантов всегда множество.

 

В том же линуксе есть такое понятие bottom half.

При этом логику работы прерывания разбивают на две части

1. то что обязательно должно исполниться в обработчике прерывания.

2. то что обязанно исполниться после обработчика прерывания (например обработка данных), но до любого юзеского кода. Т.е. после прерывания исполняется системный процесс, который может быть в том числе прерван прерываниями.

 

в PC архитектуре когда на одном физическом прерывании может несколько девайсов висеть

Это к архитектуре никакого отнощения не имеет, у меня вот прямо сейчас перед носом 16 на одном

прерывании висят. И разбирается кто вылез обработчик конкретного прерывания, который знает

как разобраться "кто сказал Гав" а не некая абстрактная прокладка для всех прерываний вместе взятых.

 

Давайте видеть всю фразу, а не её части. PC архитектуру я приводил как пример, и то что Вы умеете разрулить "кто сказал Гав" заложенно в Вашей железячно-програмной архитектуре. Возвращаясь же к PC архитектуре там в случае нескольких девайсов на одной линии прерывания однозначно определить источник не возможно, и приходится ОС (точнее её универсальному обработчику прерывания) вызывать по очереди все зерегистрированные для данной линии обработчики, а уже конкретный обработчик первым делом проверяет своё железо на факт наличия прерывания, и именно по этому не советуют иметь несколько девайсов, особенно скоростных на одной линии прерывания.

 

 

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

Сильно. Т.е. девайса нет (не вставили), драйвера нет(не загрузили) а обработчик прерывания - вот он уже есть и готов работать с неведомым ему железом на неведомом прерывании.

 

Если Вы про универсальный обработчик - то да! Он может быть, но в нём нет кода по работе с неведомым железом, в нём есть код по вызову (или не вызову) зарегистрированного(ых) обработчика(ов). А регистрируют эти обработчики например драйвера при их загрузке и после инициализации железа.

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

 

 

Ну и как доп. уровень абстракции когда писатель драйвера конкретной железки, не занимается программированием MMU или там контроллера прерываний (как то запись в VICVectAddr :) ), а использует допустимые (документированные) для данной ОС механизмы.

Живые примеры вышеописанного "ненавязчивого сервиса" имеют место быть, только зачем для этого обязательно иметь некую абстрактную прокладку перед или после собственно обработчика прерывания, который будет писать писатель драйвера?

 

Про обязательность везде и всего я не говорил. :)

 

 

Чем навороченнее ОС тем больше вариантов.

Навернуть можно много чего, вопрос зачем?

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

захочу разрешить в одном (только упаси боже не во всех зараз) обработчике вложенные прерывания?

Нафига мне тогда такой сервис?

 

Во первых я сам в LPC пользую

ldr     pc,[pc,#-0xFF0]

При этом я не пользую ОС.

 

Во вторых мы перевели разговор в сторону прерываний в ОС.

А вот с этого места, пожалуйста поподробнее. Очень люблю про OSы думать. Заинтриговали.

ОС-ы бывают большие и маленькие, простые и сложные.

Писать их может один человек, а может и тысяча.

 

Ну и как пример оправданности оверхеда с тем же VICVectAddr:

Допустим Вы участвуете в разработке некой ОС или драйверов к ней.

Допустим Вам надо написать драйвер UART совместимого с x550.

Помимо всего прочего в драйвере нужен обработчик прерывания от UART-а.

Теперь вопрос: Вы хотите при этом досканально изучить все платформы на которых работает эта ОС (ну или по крайней мере есть UART совместимый с x550) и все возможные контроллеры прерываний на этих платформах чтобы использовать эти прерывания?

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


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

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

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

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

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

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

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

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

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

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