реклама на сайте
подробности

 
 
> Вложенные прерываня
moonrock
сообщение Jul 7 2006, 20:39
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 166
Регистрация: 24-03-05
Из: Санкт-Петербург
Пользователь №: 3 661



Всем привет, недавно начал разбираться с LPC2132, среда - Keil uVision,
и вот встал вопрос, как сделать, чтобы прерывания с высшим приоритетом могли прерывать исполнение обработчиков прерываний с низшим приоритетом?
Go to the top of the page
 
+Quote Post
4 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 48)
DASM
сообщение Jul 7 2006, 22:04
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(moonrock @ Jul 8 2006, 00:39) *
Всем привет, недавно начал разбираться с LPC2132, среда - Keil uVision,
и вот встал вопрос, как сделать, чтобы прерывания с высшим приоритетом могли прерывать исполнение обработчиков прерываний с низшим приоритетом?

А никак. Прерывания всего два IRQ и FIQ. Есть конечно разные приоритеты в VIC - но их смысл только в том, какое из нескольких прерываний (если случилось несколько) будет вызвано при разрешении прерываний.
Go to the top of the page
 
+Quote Post
Andrew2000
сообщение Jul 7 2006, 22:40
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 421
Регистрация: 25-12-04
Пользователь №: 1 675



Цитата(DASM @ Jul 8 2006, 02:04) *
А никак.

Ну, не правда. Вложенные прерывания возможны. Чтоб приоритеты - надо будет маску прерываний ручками подправлять.
В книге, которая про ARM LPC по-русски (забыл как называется, под рукой нет) это рассматривается (поищите по конфе).

А заодно (почти в тему) - вот попадаю я в обработчик IRQ по умолчанию и хочу перевести бит-флаги в номер прерывания (чтоб по таблице функцию-обработчик найти), т.е. мне надо узнать позицию (номер бита) младщей единицы (в XScale инструкция CLZ есть, а в LPC?).

Написал такое, но асм для ARM я почти не знаю, может кто подчкажет как оптимизировать?

/* in: r3 - bit mask */
/* out: r1 - int num */
MOV r1,#0
findirqstart:
AND r4, a3, #1
CMP r4, #0
BNE findirqend

ADD r1, r1, #1
MOV r3, r3, lsr #1
B findirqstart
findirqend:
Go to the top of the page
 
+Quote Post
moonrock
сообщение Jul 7 2006, 22:44
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 166
Регистрация: 24-03-05
Из: Санкт-Петербург
Пользователь №: 3 661



как я понимаю, такое ограничение накладывает контроллер прерываний филипса, а есть ли вообще контроллеры, которые это позволяют? Ведь, если я не ошибаюсь, такое может делать AVR...
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jul 7 2006, 23:07
Сообщение #5


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Извращенцы вы тут все. Говорят о том, что не знают. Даже помогать после этого не хочется.

На АРМе это всё делается элементарно. Почитайте в хэлпе об __nested
Может потом на вопросы отвечу.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 7 2006, 23:41
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Читать лучше не абстрактные хелпы, а обратиться к первоисточнику. Сразу отпадут многие вопросы.
Go to the top of the page
 
+Quote Post
DASM
сообщение Jul 8 2006, 05:01
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



да... был неправ. Всем спасибо, век живи - век учись
Go to the top of the page
 
+Quote Post
moonrock
сообщение Jul 8 2006, 09:23
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 166
Регистрация: 24-03-05
Из: Санкт-Петербург
Пользователь №: 3 661



Всем большое спасибо, а вот тот ответ, который я хотел услышать:
ARM 7 аппаратно НЕ поддерживает вложенные прерывания, но обеспечить их можно софтварным путём, используя следующие асмовые макросы
#define IENABLE /* Nested Interrupts Entry */ \
__asm { MRS LR, SPSR } /* Copy SPSR_irq to LR */ \
__asm { STMFD SP!, {LR} } /* Save SPSR_irq */ \
__asm { MSR CPSR_c, #0x1F } /* Enable IRQ (Sys Mode) */ \
__asm { STMFD SP!, {LR} } /* Save LR */ \

#define IDISABLE /* Nested Interrupts Exit */ \
__asm { LDMFD SP!, {LR} } /* Restore LR */ \
__asm { MSR CPSR_c, #0x92 } /* Disable IRQ (IRQ Mode) */ \
__asm { LDMFD SP!, {LR} } /* Restore SPSR_irq to LR */ \
__asm { MSR SPSR_cxsf, LR } /* Copy LR to SPSR_irq */ \

и втыкать их перед и после того кода обработчика прерывания более низким приоритетом, который мы хотим прерывать
ещё раз всем спасибо
Go to the top of the page
 
+Quote Post
yuri_t
сообщение Jul 8 2006, 10:17
Сообщение #9


Частый гость
**

Группа: Свой
Сообщений: 163
Регистрация: 24-08-05
Пользователь №: 7 937



IMHO,без крайней необходимости с nested interrupt в ARM7/9 лучше не связываться -
весьма коварная штука. Ну а если все таки без этого никак, рекомендую использовать
код из книги A.Sloss,D.Symes,C.Wright, ARM System Developer's Guide - Designing and
Optimizing System Software
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 8 2006, 10:38
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(moonrock @ Jul 8 2006, 12:23) *
ARM 7 аппаратно НЕ поддерживает вложенные прерывания

Осталось выяснить КТО аппаратно подерживает сохранение контекстов для КАЖДОГО из
возможных прерываний :-)). На самом деле достоинством является вообще наличие аппаратно переключаемого стека и собственных регистров FIQ и IRQ. Таким образом "софтовая" организация
вложенных прерываний является абсолютно естественной а не каким-то "извращением" являющимся дурной особенностью ARM7.

Цитата(yuri_t @ Jul 8 2006, 13:17) *
IMHO,без крайней необходимости с nested interrupt в ARM7/9 лучше не связываться -
весьма коварная штука.

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 8 2006, 11:22
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(moonrock @ Jul 8 2006, 13:23) *
...но обеспечить их можно софтварным путём, используя следующие асмовые макросы

А вот это не советую. Лучше потратить чуть больше времени, и оформить вход и выход из прерывания в виде ассемблерного модуля. В этом случае результат не будет зависеть от компилятора и степени вашего с ним взаимопонимания.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jul 8 2006, 12:14
Сообщение #12


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Те же, кто не хочет использовать много асма, могут писать всё на Си и при этом не бояться что что-то плохо будет работать. Это не так. У меня во многих прогах уровень вложенности может доходить до 5-8 и всё работает стабильнее некуда. На асме написан только стартап файл. Поэтому рекомендую, если в программе полезны вложенные прерывания - используйте их наздоровье. Самые критичные прерывания разумеется должны быть непрерываемыми (без __nested). А так, в АРМ7 всё сделано красиво, если кто не понимает почему, их проблемы. Да, и ещё. Прерывания без __nested работают на стеке IRQ|FIQ. А объявленные с __nested работают на стеке основной программы, и ещё в стеке IRQ|FIQ дополнительно занимают 3-4 слова.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 8 2006, 12:49
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(GetSmart @ Jul 8 2006, 15:14) *
У меня во многих прогах уровень вложенности может доходить до 5-8

Нашли, чем гордится :-(((
Цитата
и всё работает стабильнее некуда.

Ну на принципиальную нестабильность механизма вложенности никто и не жаловался...
Если у Вас простейшая системка, хоть и 8 прерываниями, но простейшая с мало или не зависящими от результатов работы друг друга обработчиками, то проблем не будет особых. Ну а если нужно будет разруливать все нюансы взаимодействия недозавершенных обработчиков с их прервавшими и т.д., то уже потенциальных ошибок много больше :-(. Разруливание опять таки в обработчиках, что есть дополнительный код и время.
Цитата
Да, и ещё. Прерывания без __nested работают на стеке IRQ|FIQ. А объявленные с __nested работают на стеке основной программы, и ещё в стеке IRQ|FIQ дополнительно занимают 3-4 слова.

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

В общем случае нужно СИЛЬНО думать и все взвешивать перед тем как использовать вложенные прерывания.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Andrew2000
сообщение Jul 8 2006, 13:00
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 421
Регистрация: 25-12-04
Пользователь №: 1 675



А на мой вопрос про завменитель CLZ кто-нить может ответить?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 8 2006, 13:06
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(GetSmart @ Jul 8 2006, 16:14) *
Те же, кто не хочет использовать много асма, могут писать всё на Си...

Я лишь предложил способ, пригодный для использования на любом компиляторе. Слово __nested ADS, например, не знает.

Цитата(Andrew2000 @ Jul 8 2006, 17:00) *
А на мой вопрос про завменитель CLZ кто-нить может ответить?

Могли бы уже и сами посмотреть список команд для архитектуры V4. Нет там прямой замены.

P.S. ztigo: за раскрытие темы подводных камней a14.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 8 2006, 13:08
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Andrew2000 @ Jul 8 2006, 16:00) *
А на мой вопрос про завменитель CLZ кто-нить может ответить?

В ядре ARM7 нет. Если нужна скорость - используйте _сразу_ полную или частичную таблицу.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Andrew2000
сообщение Jul 8 2006, 13:48
Сообщение #17


Местный
***

Группа: Свой
Сообщений: 421
Регистрация: 25-12-04
Пользователь №: 1 675



Цитата(aaarrr @ Jul 8 2006, 17:06) *
Могли бы уже и сами посмотреть список команд для архитектуры V4. Нет там прямой замены.

Знаю, что нет, поэтому (повторю вопрос)

Написал такое, но асм для ARM я почти не знаю, может кто подскажет как оптимизировать?

/* in: r3 - bit mask */
/* out: r1 - int num */
MOV r1,#0
findirqstart:
AND r4, a3, #1
CMP r4, #0
BNE findirqend

ADD r1, r1, #1
MOV r3, r3, lsr #1
B findirqstart
findirqend:


Про таблицу не понял, ну младшую 1 выделить не сложно, а дальше...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 8 2006, 14:00
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Andrew2000 @ Jul 8 2006, 16:48) *
Про таблицу не понял, ну младшую 1 выделить не сложно, а дальше...

Таблица содержащая номер бита или _сразу_ указатель на функцию.
Если предполагается работа с полноразрядным числом, то можно для экономии размера таблицы использовать сокращенную 16, 8 или 4 битную.
0x0 ?
0x1 0
0x2 1
0x3 0
0x4 2
0x5 0
0x6 1
0x7 0
0x8 3
0x9 0
......


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 8 2006, 14:12
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Andrew2000 @ Jul 8 2006, 17:48) *
Написал такое, но асм для ARM я почти не знаю, может кто подскажет как оптимизировать?

Здесь посмотрите. Пост №48 by sergeeff.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jul 8 2006, 15:22
Сообщение #20


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(zltigo @ Jul 8 2006, 16:38) *
Не коварнее организации вложенных прерываний на любом другом процессоре, но проектировать систему со вложенными прерываниями действительно нужно только в случае крайней необходимости.

Ага. Скажите прямо, проектировать систему в которой будут сидеть на прерываниях более одного периферийного устройства крайне опасно. Бог его знает, что может произойти. И если в моей программе вдруг потребовалось одновременно обрабатывать все 8 capture-входов, PWM, два UARTа, RTC и пару вшешних прерываний, то это ну очень крайняя необходимость, которая у других никогда не возникает. Причём всё бы ничего, если бы capture не требовали максимально быстрого отклика. А так пришлось все прерывания кроме них сделать вложенными. Гордится этим? Слишком мелко как-то. Я бы гордился скажем 20-ю вложенными прерываниями. Если у вас ничего интересного нет по поводу смешивания вложенных и невложенных прерываний и как с помощью их комбинаций можно оптипизировать систему в целом, то можете говорить и дальше что это плохо и неразумно. Многие с удовольствием послушают.

Сообщение отредактировал GetSmart - Jul 8 2006, 15:26


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 8 2006, 15:52
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(GetSmart @ Jul 8 2006, 18:22) *
И если в моей программе вдруг потребовалось одновременно обрабатывать все 8 capture-входов, PWM, два UARTа, RTC и пару вшешних прерываний, то это ну очень крайняя необходимость, которая у других никогда не возникает. Причём всё бы ничего, если бы capture не требовали максимально быстрого отклика. А так пришлось все прерывания кроме них сделать вложенными.

Ну и где в описанной системе 8 "УРОВНЕЙ ВЛОЖЕННОСТИ" помянутые в ПЕРВОНАЧАЛЬНОМ посте???
В этом черным по белому описан вариант одного уровня, причем его наличие обосновано, хотя и не понятно, почему-бы не использовать для CAP FIQ, если конечно у Вас не дебильноватый контроллер типа STR7..... В принципе именно армовские IRQ+FIQ без дополнительной организации вложенности достаточно хорошо закрывают массу вариантов применения, в том числе и описанный Вами.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
DASM
сообщение Jul 8 2006, 16:42
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



А вот и не подеретесь unsure.gif smile3009.gif
Zltigo - а чего в ентих STR дебильного ? Просто интересно.. Вкратце, пару слов
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 8 2006, 17:17
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(DASM @ Jul 8 2006, 19:42) *
Zltigo - а чего в ентих STR дебильного ? Просто интересно.. Вкратце, пару слов

Там на FIQ вешаются _только_ Watchdog и Timer0 - абсолютно необъяснимая дурь.

Да и в остальном контроллер прерываний там заметно примитивнее :-( по отношению к прочим сделанным производителями чипов по ARMовским лекалам.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
DASM
сообщение Jul 8 2006, 17:38
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



a14.gif Да уж... Мне как-то повезло... Ни разу FIQ не надо было и вложенность тоже... Отсюда гигантская дыра в знаниях =)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jul 8 2006, 17:38
Сообщение #25


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(zltigo @ Jul 8 2006, 21:52) *
Ну и где в описанной системе 8 "УРОВНЕЙ ВЛОЖЕННОСТИ" помянутые в ПЕРВОНАЧАЛЬНОМ посте???

Собственно 8 уровней мне не надо было. Они возникают сами по себе при объявлении любого прерывания __nested. Поэтому если в системе 8 прерываний, 2 простых, 6 __nested, то если никак дополнительно не извращаться, будут именно 7 уровней вложенности. А теперь почему они сделаны __nested. Например, после приёма байта по UARTпрямо в прерывании вызывается драйвер связи, который может долго не возвращать управление, ну скажем до 100 мкс. Всё это время он не мешает никаким прерываниям с более высоким приоритетом. А в некоторых случаях (приём полного пакета) он ещё и взводит софтовое прерывание с более низким приоритетом. Так, что как только это прерывание завершится и если ничего более важного не произойдёт, управление вернётся не в основную прогу, а в софтовое прерывание связи. В нём вообще может управление застрять на десятки миллисекунд. И никто не обломается! Никаких критических секций и прочих извращений для этого применять не нужно вообще. Всё продумано и очень просто в применении. Бояться вложенных прерываний - в лес не ходить.

Насчёт FIQ'ов, я всё прекрасно знал. И всё-таки решил сделать так. Всё написано на Си, никаких макросов.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 8 2006, 18:41
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(GetSmart @ Jul 8 2006, 20:38) *
Они возникают сами по себе при объявлении любого прерывания __nested.

Когда что-то "возникает само по себе" это не радует :-(. А реально никто не мешает для описанного Вами случая в __nested запретить прерывание одного __nested другим ввиду ПОЛНОЙ НЕНУЖНОСТИ сего действия. И я не назвал-бы это "извращением" - напротив. Если-бы в ARMообразных контроллерах могли назначаться одинаковые приоритеты для разных источников, то это вообще реализовывалось без каких-либо дополнительных телодвижений.
Цитата
А теперь почему они сделаны __nested.

Это не нуждается в дополнительных объяснениях - "надо быстро реагировать на CAP" было вполне достаточно.
Цитата
Бояться вложенных прерываний - в лес не ходить.

Я не призываю их бояться я сам их использую, просто их не надо использовать без необходимости и уж точно бороться с возникающими "сами по себе" побочными эффектами в виде вложенности в местах, где это без надобности. Ибо, как минимум, ведет к дополнительным затратам временных ресурсов и памяти. При этом можно получить неожиданные проблемы (особенно при дописывании через годик-другой) при работе обработчиков с общими ресурсами. При совсем уже чрезмерном увлечении длинными вложенными обработчиками можно и повторный вызов обработчика схлопотать, от которого тоже надо защиту вписывать. В общем оно это надо без крайней необходимости?
Цитата
Насчёт FIQ'ов, я всё прекрасно знал. И всё-таки решил сделать так.

Т.е. для конкретного описанного случая запутаннее и тормознее :-( без явной на то необходимости, а только по причине наличия в EWARM
удобного ключевого слова __nested :-(.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jul 8 2006, 19:32
Сообщение #27


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата
можно и повторный вызов обработчика схлопотать

Повторный вызов не схлопотать. Запрещаются все приоритеты равные и ниже текущего. А то, что нельзя делать одинаковые приоритеты я и сам жалею. Помню как удобно было на 51/52 процах с трёхуровневой системой прерываний. Быстро и удобно.

В данном вопросе только один минус - лишняя многоуровневость. Но гораздо больше плюсов. Особенно быстрое время реакции на все прерывания с учётом приоритетов. А медленные софтверные прерывания вообще не сделать без вложенности.

Цитата
просто их не надо использовать без необходимости

Не-а. Я бы советовал не использовать обычные прерывания без особой необходимости. Особенно длинные или использующие много стека.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
moonrock
сообщение Jul 8 2006, 19:37
Сообщение #28


Частый гость
**

Группа: Свой
Сообщений: 166
Регистрация: 24-03-05
Из: Санкт-Петербург
Пользователь №: 3 661



блин, тут все такие умные, один умней другого, аж страшно задавать следующий глупый вопрос smile.gif , но всё же задам: мой компилятор(keil uVision) не знает ключевое слово __nested, чем вы пользуетесь?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 8 2006, 20:02
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(moonrock @ Jul 8 2006, 22:37) *
мой компилятор(keil uVision) не знает ключевое слово __nested, чем вы пользуетесь?

1. Я не полльзуюсь Keil.
2. А зачем своими руками выдрав и отпостив из кейловских рекомендаций два макроса спрашивать
чем пользоваться в Keil???

Не сильно страшно?





Цитата(GetSmart @ Jul 8 2006, 22:32) *
Не-а. Я бы советовал не использовать обычные прерывания без особой необходимости. Особенно длинные или использующие много стека.

Без коментариев.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jul 8 2006, 20:02
Сообщение #30


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Я старым (уже) IAR 4.20
Тут где-то выкладывали ссылку на 4.30, а может даже и на 4.40.


Цитата(zltigo @ Jul 9 2006, 02:02) *
Без коментариев.

Без коментариев.

Сообщение отредактировал GetSmart - Jul 8 2006, 20:05


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Andrew2000
сообщение Jul 10 2006, 15:53
Сообщение #31


Местный
***

Группа: Свой
Сообщений: 421
Регистрация: 25-12-04
Пользователь №: 1 675



Цитата(aaarrr @ Jul 8 2006, 18:12) *
Цитата(Andrew2000 @ Jul 8 2006, 17:48) *

Написал такое, но асм для ARM я почти не знаю, может кто подскажет как оптимизировать?

Здесь посмотрите. Пост №48 by sergeeff.

Спасибо, то, что надо.
Go to the top of the page
 
+Quote Post
Nixon
сообщение Jul 10 2006, 16:08
Сообщение #32


Гуру
******

Группа: Админы
Сообщений: 2 736
Регистрация: 17-06-04
Из: Киев
Пользователь №: 48



Цитата(moonrock @ Jul 8 2006, 22:37) *
блин, тут все такие умные, один умней другого, аж страшно задавать следующий глупый вопрос smile.gif , но всё же задам: мой компилятор(keil uVision) не знает ключевое слово __nested, чем вы пользуетесь?

Keil не нужно __nested для описания вложенных прерываний. Достаточно пользоваться макросами IENABLE и IDISABLE в функции обработчика прерывания. Очень хорошие примеры вложенных прерываний (там почти все обработчики сделаны этими макросами с поддержкой вложенных прерываний) есть у филипса в примерах кода к lpc21xx (адрес не знаю, искать "code.bundle.lpc213x.lpc214x.uvision.zip").

В качестве примера
Код
void EINT1_Handler (void) __irq
{
    EXTINT = EINT1;        /* clear interrupt */
        
    IENABLE;            /* handles nested interrupt */
    eint1_counter++;
    if ( eint1_counter & 0x01 )    /* alternate the LED display */
    {
    IOSET1 = 0x000F0000;    /* turn off P1.20~23 */    
    IOCLR1 = 0x00F00000;    /* turn on P1.16~19 */
    }
    else
    {
    IOSET1 = 0x00F00000;    /* turn on P1.20~23 */    
    IOCLR1 = 0x000F0000;    /* turn off P1.16~19 */
    }
    IDISABLE;
    VICVectAddr = 0;        /* Acknowledge Interrupt */
}


Сами макросы тоже просты
Код
// Macros for Interrupt Nesting
#define IENABLE                             /* Nested Interrupts Entry */   \
  __asm { MRS     LR, SPSR      }           /* Copy SPSR_irq to LR     */   \
  __asm { STMFD   SP!, {LR}     }           /* Save SPSR_irq           */   \
  __asm { MSR     CPSR_c, #0x1F }           /* Enable IRQ (Sys Mode)   */   \
  __asm { STMFD   SP!, {LR}     }           /* Save LR                 */   \

#define IDISABLE                            /* Nested Interrupts Exit  */   \
  __asm { LDMFD   SP!, {LR}     }           /* Restore LR              */   \
  __asm { MSR     CPSR_c, #0x92 }           /* Disable IRQ (IRQ Mode)  */   \
  __asm { LDMFD   SP!, {LR}     }           /* Restore SPSR_irq to LR  */   \
  __asm { MSR     SPSR_cxsf, LR }           /* Copy LR to SPSR_irq     */   \


--------------------
Вам помочь или не мешать?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 10 2006, 16:25
Сообщение #33


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Nixon @ Jul 10 2006, 19:08) *
В качестве примера
Код
void EINT1_Handler (void) __irq
{
    EXTINT = EINT1;        /* clear interrupt */
        
    IENABLE;            /* handles nested interrupt */
         ....................
    IDISABLE;
    VICVectAddr = 0;        /* Acknowledge Interrupt */
}
Скорее всего я чего-то не понимаю, но все же: как может вызваться в этом примере вложенное прерывание если VICVectAddr = 0; стоит в самом конце обработчика? Ведь пока не сделан VICVectAddr = 0 контроллер не выдаст адрес следующего обработчика?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 10 2006, 16:34
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Сергей Борщ @ Jul 10 2006, 20:25) *
Скорее всего я чего-то не понимаю, но все же: как может вызваться в этом примере вложенное прерывание если VICVectAddr = 0; стоит в самом конце обработчика? Ведь пока не сделан VICVectAddr = 0 контроллер не выдаст адрес следующего обработчика?

До записи VICVectAddr может быть вызвано только прерывание с более высоким приоритетом.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 10 2006, 17:06
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(aaarrr @ Jul 10 2006, 19:34) *
До записи VICVectAddr может быть вызвано только прерывание с более высоким приоритетом.

Проверить достаточно легко, можно и о PrimeCell почитать первоисточник. Но по логике вещей так быть не может, ибо в этом случае при возникновении последовательно прерываний от разных источников будут потеряны все низкоприоритетные, если процесс обработки не успеет считать значение из VicVectAddr и оно будет перезаписано более приоритетным адресом обработчика. В общем как ни крути именно процедура произвольной записи в VicVectAddr логично разрешает занесение нового (вне зависимости от его приоритета) значения в этот регистр. Ну а примеры, как это почти всегда :-( бывает просто фуфло.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 10 2006, 17:12
Сообщение #36


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(zltigo @ Jul 10 2006, 21:06) *
Проверить достаточно легко, можно и о PrimeCell почитать первоисточник.

Вот и почитайте:
Код
Reading from the Vector Interrupt Address Register,
VICVECTADDR, provides the address of the ISR, and updates the interrupt priority
hardware that masks out the current, and any lower priority interrupt requests. Writing
to the VICVECTADDR Register indicates to the interrupt priority hardware that the
current interrupt is serviced, enabling lower priority or the same priority interrupts to be
removed, and for the interrupts to become active to go active.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 10 2006, 17:25
Сообщение #37


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(aaarrr @ Jul 10 2006, 20:12) *
Код
Reading from the Vector Interrupt Address Register,
......

Достаточно убедительно и в такой трактовке работоспособно, хотя настораживает фраза "the same priority", которых быть не должно.
Короче желательно проверить электроникой, что и сделаю сегодня.

Проверено!
Действительно, чтение " Vector Interrupt Address Register" несет дополнительную функциональную нагрузку в виде перетасовки приоритетов и даже без последующей записи
позволяет функционировать более приоритетным прерываниям. Это хорошо, обязательно использую!
Эксперимент проводился на LPC2148 у которого контроллер прерываний от ARM прикручен.

Сообщение отредактировал zltigo - Jul 10 2006, 18:00


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Angle
сообщение Oct 1 2007, 10:55
Сообщение #38


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 8-08-07
Из: Екатеринбург
Пользователь №: 29 638



Подскажите, если кто знает, пример кода для обработчика вложенных прерываний для AT91SAM7A3, компилятор Keil.
Go to the top of the page
 
+Quote Post
xelax
сообщение Oct 2 2007, 05:52
Сообщение #39


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Цитата(Angle @ Oct 1 2007, 14:55) *
Подскажите, если кто знает, пример кода для обработчика вложенных прерываний для AT91SAM7A3, компилятор Keil.


Из примеров на сайте atmela wink.gif Исходя из примера вложенность прерываний делается просто.
В филипсах таким вопросом не озадачивался, поэтому не совсем понятно зачем народ здесь копья ломает 07.gif

Код
irq_handler:
/*- Manage Exception Entry */
/*- Adjust and save LR_irq in IRQ stack */
        sub      lr, lr, #4
        stmfd    sp!, {lr}
/*- Save r0 and SPSR in IRQ stack */
        mrs      r14, SPSR
        stmfd    sp!, {r0,r14}

/*- Write in the IVR to support Protect Mode */
/*- No effect in Normal Mode */
/*- De-assert the NIRQ and clear the source in Protect Mode */
        ldr      r14, =AT91C_BASE_AIC
        ldr      r0 , [r14, #AIC_IVR]
        str      r14, [r14, #AIC_IVR]

/*- Enable Interrupt and Switch in Supervisor Mode */
        msr      CPSR_c, #ARM_MODE_SVC

/*- Save scratch/used registers and LR in User Stack */
        stmfd    sp!, {r1-r3, r12, r14}

/*- Branch to the routine pointed by the AIC_IVR */
        mov      r14, pc
        bx       r0

/*- Restore scratch/used registers and LR from User Stack */
        ldmia    sp!, {r1-r3, r12, r14}

/*- Disable Interrupt and switch back in IRQ mode */
        msr      CPSR_c, #ARM_MODE_IRQ | I_BIT

/*- Mark the End of Interrupt on the AIC */
        ldr      r14, =AT91C_BASE_AIC
        str      r14, [r14, #AIC_EOICR]

/*- Restore SPSR_irq and r0 from IRQ stack */
        ldmia    sp!, {r0,r14}
        msr      SPSR_cxsf, r14

/*- Restore adjusted  LR_irq from IRQ stack directly in the PC */
        ldmia    sp!, {pc}^
Go to the top of the page
 
+Quote Post
Tannen
сообщение Jun 18 2009, 13:17
Сообщение #40


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 16-02-08
Пользователь №: 35 104



Мои пять копеек вопроса про вложенные прерывания. на LPC2148 делаю захват CAP0 по таймеру TIMER0.
По отдельности от сигнала подаваемого на все 4 входа захвата( синхронный фронт на все 4 входа) - все работает - счетчик импульсов тикает.
Когда все вместе ( захватывается только 1-он первый канал (((
пишу под IAR. мой код прерываний - т.к. инициализация корректна
Код
__irq __nested __arm void irq_handler (void)
{
void (*interrupt_function)();
  unsigned int vector;
   vector = VICVectAddr;                   // Get interrupt vector.
   interrupt_function = (void(*)())vector; // Call MM_TIMER0_ISR thru pointer
  (*interrupt_function)();  // Call vectored interrupt function
  VICVectAddr = 0;          // Clear interrupt in VIC
}

void  MM_TIMER0_ISR()
{
   volatile unsigned int iPR;
  unsigned char PriA;
if(T0IR_bit.CR0INT)
  {
  
    TVK[0]++;
    if(VKN&0x01)
         {
           TCapi[0]=TCap[0];
           TCap[0] =T0CR0;
         }
    if(TVK[0]==1) VKN&=~0x01;
  T0IR_bit.CR0INT=1; // clear interrupt
  }
  
  // CAP_1
  if(T0IR_bit.CR1INT)
  {
    TVK[1]++;
    if (VKN&0x02)
    {
         TCapi[1]=TCap[1];
         TCap[1] =T0CR1;
    }
    if(TVK[1]==1) VKN&=~0x02;
   T0IR_bit.CR1INT=1;  // clear inteerupt
  }
  if(T0IR_bit.CR2INT)
  {  
     TVK[2]++;
    if (VKN&0x04)
    {
      TCapi[2]=TCap[2];
      TCap[2] =T0CR2;
    }
    if(TVK[2]==1) VKN&=~0x04;
  T0IR_bit.CR2INT=1;
  }
  
  if(T0IR_bit.CR3INT)
  {  
     TVK[3]++;
    if (VKN&0x08)
    {
      TCapi[3]=TCap[3];
      TCap[3] =T0CR3;
    }
    if(TVK[3]==1) VKN&=~0x08;
    T0IR_bit.CR3INT=1;
  }

Ну и как здесь будет реализована вложенность прерываний? ято я не так делаю ? (((
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 18 2009, 14:01
Сообщение #41


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Tannen @ Jun 18 2009, 16:17) *
Код
  T0IR_bit.CR0INT=1; // clear interrupt

что я не так делаю ? (((
В этой строчке вы сбрасываете не только этот флаг, но и все остальные. Потому что доступ к битовому полю происходит как операция "чтение-модификация-запись" чтобы не испортить остальные поля. Откуда же компилятору знать, что для этого регистра так делать нельзя. Это раз.
Второе - непонятно, зачем вам тут вложенные прерывания. Разрешаются вложенные прерывания только более высокого приоритета, т.е. в этот же обработчик вы не попадете.
Третье - вынесите свой irq_handler в ассемблерный файл в виде команды LDR PC,[PC, #-0x0FF0] прямо на векторе прерывания, а VICVectAddr = 0 и __irq __arm перенесите в каждый обработчик. Вот тут пример для SAM7, для LPC меняются имена регистров. Это позволит компилятору генерить максимально эффективные (короткие) прологи/эпилоги и существенно повысит скорость обработки прерываний, а вам позволит использовать __nested только для тех обработчиков, в которых он действительно нужен (например, в самых приоритетных он не нужен - прервать такой обработчик некому - и только замедляет эти самые важные обработчики).
Четвертое - вам надо в этом обработчике организовать цикл do{}while(T0IR);


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
KeiserSose
сообщение Jun 19 2009, 07:30
Сообщение #42





Группа: Новичок
Сообщений: 4
Регистрация: 17-11-08
Пользователь №: 41 713



Цитата(GetSmart @ Jul 8 2006, 22:32) *
Повторный вызов не схлопотать. Запрещаются все приоритеты равные и ниже текущего. А то, что нельзя делать одинаковые приоритеты я и сам жалею. Помню как удобно было на 51/52 процах с трёхуровневой системой прерываний. Быстро и удобно.

В данном вопросе только один минус - лишняя многоуровневость. Но гораздо больше плюсов. Особенно быстрое время реакции на все прерывания с учётом приоритетов. А медленные софтверные прерывания вообще не сделать без вложенности.


Не-а. Я бы советовал не использовать обычные прерывания без особой необходимости. Особенно длинные или использующие много стека.


Повторный вызов можно схлопотать элементарно. VicVectAddr=0 открывает ВСЕ прерывания. Нужно явно маскировать и восстанавливать приоритеты.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 19 2009, 07:36
Сообщение #43


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(KeiserSose @ Jun 19 2009, 11:30) *
Повторный вызов можно схлопотать элементарно. VicVectAddr=0 открывает ВСЕ прерывания. Нужно явно маскировать и восстанавливать приоритеты.


Ошибаетесь:
Цитата
Writing to the VICVECTADDR Register indicates to the interrupt priority hardware that the
current interrupt is serviced, enabling lower priority or the same priority interrupts to be
removed, and for the interrupts to become active to go active.
Go to the top of the page
 
+Quote Post
KeiserSose
сообщение Jun 19 2009, 09:11
Сообщение #44





Группа: Новичок
Сообщений: 4
Регистрация: 17-11-08
Пользователь №: 41 713



Цитата(aaarrr @ Jun 19 2009, 10:36) *
Ошибаетесь:


Если мы обсуждаем версию ARM PrimeCell, используемую в большинстве LPC, то ошибаетесь Вы. Действительно, при чтении VicVectAddr, контроллер повышает приоритет разрешенных прерываний до уровня текущего прерывания. Это обеспечивает правильный вход в стэк прерываний, но только до первой записи в VicVectAddr, что сбрасывает логику контроллера. Таким образом, незавершенные ISR могут прерываться прерываниямм с более низким приоритетом, если прерывания этого типа разрешены в CPSR. Макросы Keil'a просто открывают прерывания. Никакого "Handle nested interrupt" в них нет. VicSWPriorityMask должен быть использован для правильной реализации вложенности.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 19 2009, 10:07
Сообщение #45


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(KeiserSose @ Jun 19 2009, 13:11) *
Если мы обсуждаем версию ARM PrimeCell, используемую в большинстве LPC, то ошибаетесь Вы.

Во-первых, и так понятно, что речь шла о pl190, у pl192 этот регистр называется VICADDRESS.
Во-вторых читаем (pl192):
Цитата
The PrimeCell VIC implements two forms of interrupt priority masking:

Hardware masking
The hardware masking is applied whenever an interrupt is being serviced,
either with a read from the VICADDRESS Register, or by asserting the
VICIRQACK input when the VIC port is used. This prevents other
active interrupts of an equal or lower priority generating a new IRQ while
the interrupt service routine is being executed. When the interrupt routine
has completed and the VICADDRESS Register has been written to, the
interrupt mask is cleared to allow all enabled interrupt sources through.
Note
The VICIRQSTATUS and VICRAWINTR Registers are not affected by
this masking.

Software masking
The software masking is applied using the value programmed into the
VICSWPRIORITYMASK Register. This mask is applied continuously,
and at the same time as the hardware mask when an interrupt is being
serviced.
Note
The values in the VICIRQSTATUS and VICRAWINTR Registers do not
reflect the masking by the VICSWPRIORITYMASK Register.

и еще:
Цитата
Writing to the VICADDRESS
Register indicates to the interrupt priority hardware that the current interrupt is serviced,
enabling the masking of lower priority or the same priority interrupts to be removed and
for the interrupts to become active.

И как получается вывод
Цитата
VicSWPriorityMask должен быть использован для правильной реализации вложенности.

?

Программное управление приоритетами было введено в дополнение к аппаратному, и никак его не отменяет:
Цитата
Software-programmable interrupt priority level masking added, in addition to the
hardware priority level masking.
Go to the top of the page
 
+Quote Post
KeiserSose
сообщение Jun 19 2009, 19:41
Сообщение #46





Группа: Новичок
Сообщений: 4
Регистрация: 17-11-08
Пользователь №: 41 713



Убедил. Был неправ. Вспылил.
Go to the top of the page
 
+Quote Post
Step_ARM
сообщение Jun 23 2009, 05:43
Сообщение #47


Частый гость
**

Группа: Участник
Сообщений: 132
Регистрация: 11-07-08
Пользователь №: 38 870



Половину не понял из того, что написано...
Хотя вопрос сильно интересует.
Проц. LPC2364
INT2(Р2.12) & INT3(Р2.13) подключены как счетные входы. Частоты примерно 400-500 Гц и 200-250Гц.

Обработчики такие:

__irq __nested __arm void EINT2_Handler (void)
{
EXTINT|= EINT2; /* clear interrupt */
__enable_interrupt(); /* handles nested interrupt */
//***********************************************************

ssf_o++;

//***********************************************************
VICVectAddr = 0; /* Acknowledge Interrupt */
}
__irq __nested __arm void EINT3_Handler (void)
{

EXTINT|= EINT3; /* clear interrupt */
__enable_interrupt(); /* handles nested interrupt */
//***********************************************************
count_msr++;


//***********************************************************
VICVectAddr = 0; /* Acknowledge Interrupt */
}

Короче работает только один счетчик , прерывание которого имеет больший приоритет.
Если убираю _nested и __enable_interrupt(); дела не меняет, тоже самое.

Тоже самое на 51-х, Меге и NEC работает прекрасно. Вопрос КАК извернуться? Объясните, пожалуйста , что не так...
Go to the top of the page
 
+Quote Post
meister
сообщение Jun 23 2009, 06:41
Сообщение #48


Местный
***

Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484



Цитата(Step_ARM @ Jun 23 2009, 09:43) *
Короче работает только один счетчик , прерывание которого имеет больший приоритет.
Вопрос КАК извернуться? Объясните, пожалуйста , что не так...


Когда ничего не помогает, прочтите, наконец, инструкцию.

This bit is cleared by writing a one to it, except in level sensitive mode when
the pin is in its active state.

и

стандарт языка еще, про операцию |=
Go to the top of the page
 
+Quote Post
Step_ARM
сообщение Jun 23 2009, 08:12
Сообщение #49


Частый гость
**

Группа: Участник
Сообщений: 132
Регистрация: 11-07-08
Пользователь №: 38 870



Цитата(meister @ Jun 23 2009, 10:41) *
Когда ничего не помогает, прочтите, наконец, инструкцию.

This bit is cleared by writing a one to it, except in level sensitive mode when
the pin is in its active state.

и

стандарт языка еще, про операцию |=

М-да. Сказать нечего... Заменил |= на = и все заработало.
Запарился совсем. Спасибо.
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th July 2025 - 02:21
Рейтинг@Mail.ru


Страница сгенерированна за 0.0204 секунд с 7
ELECTRONIX ©2004-2016