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

 
 
> По ARM архитектуре (LPC2106), вложенные прерывания
SasaVitebsk
сообщение Jun 16 2008, 19:52
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 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 применяю и это не для данного случая. Если это так, то как необходимо проинициилизировать, вызвать и обработать. Если можно примерчик пож.

Заранее благодарю.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 9)
zltigo
сообщение Jun 16 2008, 20:42
Сообщение #2


Гуру
******

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



Как-то все мутно изложено sad.gif. Но насколько можно понять "вложеные" тут ни сном ни духом. Просто разрешите прерывания в Вашем обработчике SWI и все.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jun 16 2008, 23:03
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(zltigo @ Jun 16 2008, 23:42) *
Как-то все мутно изложено sad.gif


Хотел просто покороче.
Имеются прерывания 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, то вроде бы всё понятно.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 17 2008, 04:50
Сообщение #4


Гуру
******

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



Туман надо ликвидировать smile.gif

Цитата(SasaVitebsk @ Jun 17 2008, 03:03) *
3) если я вызову в прерывании fiq, то оно будет обработано по выходу?

Нет, процессор тут же ломанется выполнять SWI.

Цитата(SasaVitebsk @ Jun 17 2008, 03:03) *
4) Почему в данном случае не надо сохранять SPSR_irq

Потому что процессор будет переключен в режим супервизора.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jun 17 2008, 07:12
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



значит эт мне не проокатывает. Небходимо irq nested. smile.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 17 2008, 12:29
Сообщение #6


Гуру
******

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



Если хочется прямо так, как описали, то для irq вообще ничего делать не надо, для fiq - стандартные навороты ввиде сохранения SPSR и LR в стеке (гляньте канонический пример для организации вложенности для компиляторов, которые не имеют прибамбаса __nested) и в swi обработчике разрешить irq и fiq.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 18 2008, 19:23
Сообщение #7


Гуру
******

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



Да, кстати, можете повесить длииинную обработку не на swi а на irq, "штатно" разрешить ему вложенность и софтово дергать irq из fiq. Я так как-то делал переключение контекста задачи в нештатных случаях "почти из fiq", дабы навороты по сохранетию контекста на fiq не вешать.
Обработчик в fiq взводит бит не используемого прерывания у которого установлен вектор и по выходу их fiq влетаем в обрабочик irq.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 18 2008, 23:22
Сообщение #8


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(SasaVitebsk @ Jun 17 2008, 02:03) *
Каждое N-ое прерывание fiq надо вызвать софтовое прерывание (N=56). При этом прерывание софтовое выполняется достаточно долго (3-30 прерываний fiq) и необходимо чтобы прерывания fiq и irq были бы разрешены.

Вы можете изложить объективную причину того, почему нельзя обработку этого некоего события (N=56) возложить на основной цикл программы?

Ведь только прямолинейная дубовая как бревно логика основного цикла программы с "delay_ms" могут этому помешать. Может лучше копать и что-то менять там? Сейчас у вас одно такое событие, но ведь их может быть 2, 5 ...100.. Что тогда? Под каждое свой IRQ?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 19 2008, 04:13
Сообщение #9


.
******

Группа: Участник
Сообщений: 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-ого включительно.


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


.
******

Группа: Участник
Сообщений: 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.

На первый взгляд всё. Если после этого не заработает как надо, то почитаю ещё разок повнимательнее cool.gif

Сообщение отредактировал GetSmart - May 15 2009, 21:44


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post

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

 


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


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