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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> ARM7 от Atmel. Запрет прерываний., почему он заходит в Spurious Interrupt
Shein
сообщение Jun 8 2012, 14:17
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 45
Регистрация: 4-03-07
Пользователь №: 25 855



Доброго всем времени суток.
Столкнулся с таким явлением как вызов обработчика Spurious Interrupt.
Суть вопроса:
Работа с UART через контроллер PDC. Обрабатываются прерывания END_RX и END_TX. Используются два кольцевых буфера, т.е. прием или передача по PDC идет непрерывно. Фактически работа с индексами этих буферов идет и из прерываний, и из основной программы.
Логично, что когда я, например, читаю из приемного буфера, то при обращении к индексам, запрещаю прерывания по приему END_RX. Аналогично, при записи в передающий буфер, при обращении к индексам, запрещаются прерывания передатчика END_TX.
Столкнулся с тем, что при интенсивном обмене данными, программа иногда залетает в Spurious Interrupt. Согласно даташиту, это происходит, если контроллер AIC выдал запрос на прерывание ядру, но на момент чтения вектора обработчика, запрос на прерывание уже был снят.
В процессе отладки программы эта версия абсолютно подтвердилась. Вход в Spurious Interrupt происходит если запрос на прерывание контроллеру AIC пришел в момент обработки инструкции запрета прерывания от приемника или передатчика. Соответственно запрет отрабатывается, бит interrupt pending снимается, и когда ядро читает вектор обработчика из AIC, получается что прерывания-то уже нет.

Собственно вопрос: это нормальная ситуация? Раньше у меня стояла заглушка (бесконечный цикл) на Spurious Interrupt и на всех неиспользуемых векторах в AIC. Когда на Spurious Interrupt поставил обработчик в котором просто формируется подтверждение (запись в AIC_EOICR) программа, в общем стала нормально работать. Но вызовы Spurious таки иногда наблюдаются. Вот я и думаю, оставить как есть, еле же есть некий корректный механизм, как запрещать прерывание без возникновения данного эффекта?
P.S. В догонку: наблюдал это явление на двух процессорах AT91RM3400 и AT91SAM7X256. Картина абсолютно идентичная.

Сообщение отредактировал Shein - Jun 8 2012, 14:21
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 8 2012, 14:50
Сообщение #2


Гуру
******

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



Цитата(Shein @ Jun 8 2012, 18:17) *
Собственно вопрос: это нормальная ситуация? Раньше у меня стояла заглушка (бесконечный цикл) на Spurious Interrupt и на всех неиспользуемых векторах в AIC. Когда на Spurious Interrupt поставил обработчик в котором просто формируется подтверждение (запись в AIC_EOICR) программа, в общем стала нормально работать.

Нормальная ситуация. Как раз заглушка с бесконечным циклом на Spurious - это совершенно не нормально.
Go to the top of the page
 
+Quote Post
Lotor
сообщение Jun 9 2012, 06:55
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 476
Регистрация: 3-07-07
Из: Санкт-Петербург
Пользователь №: 28 866



Эти прерывания типичны не только для атмелов, мне понравилась объяснение в этом документе от nxp - Handling of spurious interrupts in the LPC2000.


--------------------
Ковырял чукча отверткой в ухе, звук в телевизоре и пропал.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 9 2012, 06:56
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Shein @ Jun 8 2012, 20:17) *
Вот я и думаю, оставить как есть, еле же есть некий корректный механизм, как запрещать прерывание без возникновения данного эффекта?

Корректный механизм в случае работы с UART через кольцевые буфера - вообще не запрещать прерывания. Зачем их запрещать если в кольцевой RX-буфер только один писатель - ISR, а в кольцевой TX-буфер - пишет только фоновый процесс?
Go to the top of the page
 
+Quote Post
Aaron
сообщение Jun 9 2012, 09:29
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 243
Регистрация: 5-10-06
Из: Зеленоград
Пользователь №: 21 007



Если я не ошибаюсь, там же можно два буфера для передачи задавать. Один заполнился - читаем и обрабатываем его спокойно, а второй тем временем заполняется. Зачем запрещать прерывания? Ну и, конечно, из Spurious выходить надо - это по-любому, у меня в одном проекте много блокировок возможно из-за вложенных прерываний, дак там это SPU - обычное явление.
Go to the top of the page
 
+Quote Post
Shein
сообщение Jun 10 2012, 13:46
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 45
Регистрация: 4-03-07
Пользователь №: 25 855



Народ, спасибо всем большое! sm.gif Вы развеяли мои сомнения. А то ведь я пытался с этим бороться, два дня убил. smile3046.gif
Цитата(jcxz @ Jun 9 2012, 09:56) *
Корректный механизм в случае работы с UART через кольцевые буфера - вообще не запрещать прерывания. Зачем их запрещать если в кольцевой RX-буфер только один писатель - ISR, а в кольцевой TX-буфер - пишет только фоновый процесс?

По сути, почти так и есть, только для всяких проверок (на наличие принятых данных, заполнение буфера) приходится обращаться к индексам, которые изменяются в ISR. Ну и, можно сказать, перестраховался.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jun 10 2012, 14:15
Сообщение #7


Гуру
******

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



А если вот такая ситуация к примеру:
1. Фоновый процесс считывает в регистр индекс, дабы увеличить его на 1 с целью записать в FIFO новый байт для отправки.
3. Возникает прерывание по отправке данных. Считывается, опять же индекс из памяти дабы уменьшить индекс FIFO, так как очередной байт отправлен.
4. Декрементированый индекс записывается в память. Обработчик прерывания завершается.
5. Фоновый процесс инкрементирует индекс и записывает его в память.

Как Вам ситуация? sm.gif

ИМХО, запрещать прерывание нужно обязательно перед записью в буфер.


--------------------
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 10 2012, 15:53
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(prottoss @ Jun 10 2012, 20:15) *
А если вот такая ситуация к примеру:
1. Фоновый процесс считывает в регистр индекс, дабы увеличить его на 1 с целью записать в FIFO новый байт для отправки.
3. Возникает прерывание по отправке данных. Считывается, опять же индекс из памяти дабы уменьшить индекс FIFO, так как очередной байт отправлен.
4. Декрементированый индекс записывается в память. Обработчик прерывания завершается.
5. Фоновый процесс инкрементирует индекс и записывает его в память.

Как Вам ситуация? sm.gif

Зачем же делать такое кривое FIFO??? crying.gif
Цитата(prottoss @ Jun 10 2012, 20:15) *
ИМХО, запрещать прерывание нужно обязательно перед записью в буфер.

Если иметь прямые руки и писать FIFO правильно - не нужно! sm.gif
Обычная реализация FIFO для межпроцессного (и даже - межпроцессорного взаимодействия):
Два индекса (у каждого процесса свой).
Каждый процесс (или ISR) модифицирует только свой индекс, чужой индекс он может только читать. Один процесс - только пишет в FIFO, другой - только читает.
Каждый процесс двигает свой индекс записывая или читая в FIFO до тех пор, пока не упрётся в чужой индекс (что является признаком опустошения/заполнения FIFO).
Минус такой реализации - реальная ёмкость FIFO на 1 элемент меньше выделенного для него буфера. Если элементы - байты - это ерунда.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jun 10 2012, 15:56
Сообщение #9


Гуру
******

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



Цитата(jcxz @ Jun 10 2012, 21:53) *
Каждый процесс двигает свой индекс записывая или читая в FIFO до тех пор, пока не упрётся в чужой индекс (что является признаком опустошения/заполнения FIFO).
Ага, вот тут то и упрется, когда один процесс изменит, другой тож


--------------------
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 10 2012, 16:02
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Читайте внимательнее:
Цитата(jcxz @ Jun 10 2012, 21:53) *

Каждый процесс (или ISR) модифицирует только свой индекс, чужой индекс он может только читать.

Go to the top of the page
 
+Quote Post
prottoss
сообщение Jun 10 2012, 16:05
Сообщение #11


Гуру
******

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



Цитата(jcxz @ Jun 10 2012, 22:02) *
Читайте внимательнее:
Читайте внимательнее. Никто не запрещает одному индексу переехать через другой.


--------------------
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 10 2012, 16:07
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(jcxz @ Jun 10 2012, 21:53) *

Каждый процесс двигает свой индекс записывая или читая в FIFO до тех пор, пока не упрётся в чужой индекс (что является признаком опустошения/заполнения FIFO).

Go to the top of the page
 
+Quote Post
prottoss
сообщение Jun 10 2012, 16:16
Сообщение #13


Гуру
******

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



Цитата(jcxz @ Jun 10 2012, 22:07) *
Ваши красные буквы ни как меня не смущают sm.gif Еще раз вам повторяю, что один процесс должен приостановить второй, прежде чем он что то изменит в общих данных


--------------------
Go to the top of the page
 
+Quote Post
MaslovVG
сообщение Jun 10 2012, 16:17
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 210
Регистрация: 24-01-05
Из: Россия Волгодонск
Пользователь №: 2 134



Цитата(prottoss @ Jun 10 2012, 18:15) *
А если вот такая ситуация к примеру:
1. Фоновый процесс считывает в регистр индекс, дабы увеличить его на 1 с целью записать в FIFO новый байт для отправки.
3. Возникает прерывание по отправке данных. Считывается, опять же индекс из памяти дабы уменьшить индекс FIFO, так как очередной байт отправлен.
4. Декрементированый индекс записывается в память. Обработчик прерывания завершается.
5. Фоновый процесс инкрементирует индекс и записывает его в память.

Здесь вы описываете не FIFO (очередь) а а стек (последний вышол первый вышел). Почитайте Кнут "основные алгоритмы".
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 10 2012, 16:22
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(prottoss @ Jun 10 2012, 22:16) *
Еще раз вам повторяю, что один процесс должен приостановить второй, прежде чем он что то изменит в общих данных
Зачем???? И какие данные "общие"?
Go to the top of the page
 
+Quote Post

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

 


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


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