|
По ARM архитектуре (LPC2106), вложенные прерывания |
|
|
|
Jun 16 2008, 19:52
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
(Пожалуйста не предлагать варианты с ОС.) Имеется несколько прерываний. Одно объявлено как FIQ и несколько по типу IRQ через VIC. Хочу сделать одно совтовое прерывание. Во время его работы должны быть разрешены все другие прерывания (вложенные). Попытался его объявить следующим образом Код #pragma swi_number=VIC_SW // Èñïîëíåíèå êîììàíä __irq __arm __nested __swi static void ShowActive(void) Пишет об ошибке. Убрал __irq - пишет, что __nested только с __irq может быть применено. Пример из описалова по nested меня не устраивает, так как мне не надо во всех irq прерываниях разрешать fiq, а только в совтовом. Может я неправильно __swi применяю и это не для данного случая. Если это так, то как необходимо проинициилизировать, вызвать и обработать. Если можно примерчик пож. Заранее благодарю.
|
|
|
|
|
 |
Ответов
(1 - 9)
|
Jun 16 2008, 23:03
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(zltigo @ Jun 16 2008, 23:42)  Как-то все мутно изложено  Хотел просто покороче. Имеются прерывания irq от rs485 (Это просто для информации). Имеется быстрое регулярное прерывание от таймера fiq. Каждое N-ое прерывание fiq надо вызвать софтовое прерывание (N=56). При этом прерывание софтовое выполняется достаточно долго (3-30 прерываний fiq) и необходимо чтобы прерывания fiq и irq были бы разрешены. Ещё раз почитав думаю что это можно сделать двумя способами. 1 через swi. 2 посредством VIC с вызывом прерываний с софтовым вектором. Во втором случае необходимо использовать ключевое слово __nested. Хотя пока в голове туман. Вопрос если я хочу воспользоваться swi, то такие вопросы: 1) как вызвать прерывание 2) как его разрешить 3) если я вызову в прерывании fiq, то оно будет обработано по выходу? 4) Почему в данном случае не надо сохранять SPSR_irq Если я воспользуюсь irq, то вроде бы всё понятно.
|
|
|
|
|
Jun 17 2008, 04:50
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Туман надо ликвидировать  Цитата(SasaVitebsk @ Jun 17 2008, 03:03)  3) если я вызову в прерывании fiq, то оно будет обработано по выходу? Нет, процессор тут же ломанется выполнять SWI. Цитата(SasaVitebsk @ Jun 17 2008, 03:03)  4) Почему в данном случае не надо сохранять SPSR_irq Потому что процессор будет переключен в режим супервизора.
|
|
|
|
|
Jun 19 2008, 04:13
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(SasaVitebsk) Каждое N-ое прерывание fiq надо вызвать софтовое прерывание (N=56). При этом прерывание софтовое выполняется достаточно долго (3-30 прерываний fiq) и необходимо чтобы прерывания fiq и irq были бы разрешены. Я почти в каждом проекте делаю что-то очень похожее. Делается легко и непринуждённо. _swi не надо трогать, там немного по-другому делается. FIQ и IRQ выполняются в штатном режиме без особых извращений по запрету прерываний. Вобщем софтовое прерывание объявляется через _arm _irq _nested. Ему даётся самый или почти самый низкий приоритет - это как надо в проге. Разумеется в нём в начале разрешаются все проерывания (и FIQ) через __enable_interrupt, а перед концом запрещаются. После запрета сбрасывается бит данного прерывания в регистре VICSoftIntClear. А в FIQ прерывании после достижения N=56 устанавливается тот же бит прерывания в регистре VICSoftInt. Таким образом, когда FIQ закончится и не будет прерываний более приоритетных чем выбранный приоритет софтового прерывания, то выполнение перейдёт на это прерывание, а когда оно отработает, то выполнение вернётся в основную прогу например. Все прерывания с приоритетами выше софтового будут его прерывать и оперативно отрабатываться, а в софтовом при этом можно сидеть очень долго и не бояться, т.к. оно затормаживает только основную прогу. Вобщем очень удобная штука. При этом, основной проге не нужно знать об всех этих заморочках и анализировать фсякие флаги. В последней своей проге у меня даже два разных таких софтовых прерывания. Всё работает без глюков. В качестве вектора в битовой карте регистров VICSoftInt и им подобным для такого обработчика есть вектор VIC_SW (имена находятся в файле iolpc2xxx.h), но можно использовать вектор и любой другой незадействованной в проекте периферии, например VIC_WDT, VIC_DEBUGRX, VIC_DEBUGTX и другие, и даже свободные биты до 31-ого включительно.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
May 15 2009, 21:31
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
CODE В голове инициализация векторов - такая:
VICIntEnClear = (uint32_t)-1; // Очистить все прерывания VICSoftIntClear = (uint32_t)-1; // Очистить совтовые прерывания #define VIC_CNTL_ENABLE_BIT 5 VICVectCntl0 = (1<<VIC_CNTL_ENABLE_BIT) | VIC_UART0; // Прерывание от USART0 - высший приоритет VICVectAddr0 = (uint32_t)UART0_Handler; VICIntEnable = (1<<VIC_TIMER0)|(1<<VIC_UART0); // Разрешить прерывание от таймера 0 и от USART0 VICIntSelect = (1<<VIC_TIMER0); // Прерывание от таймера 0 = FIQ ... #define SHOW_INT VIC_SW // Âåêòîð ñîôòîâîãî ïðåðûâàíèÿ íà îáðàáîòêó êîììàíä
VICVectCntl15 = (1<<VIC_CNTL_ENABLE_BIT) | SHOW_INT; // Enable vector interrupt for context switcher VICVectAddr15 = (uint32_t)ShowActive; VICIntEnable = (1UL<<SHOW_INT); VICVectAddr = 0; // Reset VIC logic ...
FIQ прерывание объявлено так
__fiq __arm void FIQ_Handler() // Отображение картинки Master, Slave ... там вызов картинки if(Flag.EnShow) VICSoftInt = (1<<SHOW_INT); // Выполнить прерывание .... завершение так VICVectAddr = 0; } ....
Совтовое прерывание оформлено так __arm __nested __irq static void ShowActive(void)// Исполнение комманд ... Потом идёт кое какая критическая секция, где бы я не хотел иметь прерываний, тем не менее по JLINKу почемуто FIQ прерывания здесь разрешены ... далее я разрешаю прерывания ... __enable_interrupt(); ... из данного прерывания выхожу так ... __disable_interrupt(); VICSoftIntClear = (1<<SHOW_INT); // Сбросить совтовое прерывание VICVectAddr = 0; // TST_CLR; } ....
Что я вижу. 1) FIQ вызываются как положено 2) Ч/з нужное число прерываний FIQ устанавливается флаг совтового прерывания, и осуществляется переход на него. 3) при выходе из совтового прерывания возврат происходит не туда куда нужно VICVectAddr = 0; => ставить в конце обработчика FIQа не нужно. FIQ работает в обход VICа. В конце обработчика нужно сбросить флаги прерывания периферии, которая вызвала FIQ. В данном случае флаги прерывания таймера 0. Если же поставить сброс VIC, то могут быть аномалии в работе проги. Т.к. если FIQ прервал IRQ, то после выхода из FIQ, VIC подумает что закончилось текущее IRQ и может вызвать повторно как текущее IRQ, так и IRQ с более низким приоритетом, прервав текущее (с более высоким). static в заголовке прерывания никогда не ставлю. Честно говоря, даже не знаю зачем оно нужно. (ЗЫ. Если кто знает - расскажите. Заодно встал сегодня на грабли в CCS3.3 который ругается когда переменная вне процедуры объявлена через static, а я её в хидере пытался через extern объявить, компилеру не понравилось вместе extern static ... Для меня этот статик загадочный какой-то. Только внутри процедуры знаю для чего он используется.) Цитата Потом идёт кое какая критическая секция, где бы я не хотел иметь прерываний, тем не менее по JLINKу почемуто FIQ прерывания здесь разрешены Так и должно быть. Залетая в обработчик IRQ, проц запрещает только IRQ, а FIQ остаётся включённым, точнее каким и был раньше. Если нужна абсолютная критическая секция, то нужно "ручками" запрещать FIQ. Цитата 3) при выходе из совтового прерывания возврат происходит не туда куда нужно Очень может быть. Как уже написал раньше, сбросив VIC внутри FIQа процессор подумал, что SoftInt завершился и после этого могло вызваться любое другое прерывание, причём управление (сразу) могло не вернуться в SoftInt. Хотя в основную прогу управление вернутся не может пока не завершиться SoftInt. На первый взгляд всё. Если после этого не заработает как надо, то почитаю ещё разок повнимательнее
Сообщение отредактировал GetSmart - May 15 2009, 21:44
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|