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

 
 
 
Reply to this topicStart new topic
> Запрет прерываний при вызове функций, и их разрешение
arttab
сообщение Mar 13 2006, 02:46
Сообщение #1


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

Группа: Свой
Сообщений: 1 432
Регистрация: 7-12-04
Из: Новосибирск
Пользователь №: 1 371



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


--------------------
OrCAD, Altium,IAR, AVR....
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 13 2006, 06:56
Сообщение #2


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(arttab @ Mar 13 2006, 08:46) *
В моей программе есть вложеные функции (одна вызывает другую и т.д.). При вызове функции выключаются прерывания, но иногда мне нужно включить. вопрос если я в функции разрешаю прерывание и далее вызываю другую функцию что будет с разрешением прерываний при возврате из другой функции?

Почему это при вызове функции запрещаются прерывания? Нет такого и не было никогда. Может Вы прерывания имеете в виду - при возникновении прерывания, бит управления глобальным разрешением прерываний сбрасывается. И взводится по команде reti.

Цитата(arttab @ Mar 13 2006, 08:46) *
И если не затруднит, раскажите как в иаре можно работать управлять поведением компилятора по глобальным прерываниям.

А доку почитать? Про intrinsic функции. Там (в описании на компилятор) это все подробно расписано с примерами кода. Курить в сторону __enable_interrupt()/__disable_interrupt().


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
arttab
сообщение Mar 13 2006, 08:10
Сообщение #3


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

Группа: Свой
Сообщений: 1 432
Регистрация: 7-12-04
Из: Новосибирск
Пользователь №: 1 371



Искузми, не указал. Да глобальное прерывание выключается при входе в обработчик прерывания. Описание хорошее, наверно. Но дую вигово. поэтому и спросил, чтоб не догадываться как правильно перевести. Спасибо.

Сообщение отредактировал arttab - Mar 13 2006, 08:11


--------------------
OrCAD, Altium,IAR, AVR....
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Mar 17 2006, 14:56
Сообщение #4


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(dxp @ Mar 13 2006, 08:56) *
... __enable_interrupt()/__disable_interrupt().

Иногда удобнее следующая конструкция: __store_interrupt(); __disable_interrupt(); ... __restore_interrupt(); если неизвестно состояние флага прерываний или во вложенных вызовах с подобными конструкциями.
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 20 2006, 09:03
Сообщение #5


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(IgorKossak @ Mar 17 2006, 20:56) *
Цитата(dxp @ Mar 13 2006, 08:56) *

... __enable_interrupt()/__disable_interrupt().

Иногда удобнее следующая конструкция: __store_interrupt(); __disable_interrupt(); ... __restore_interrupt(); если неизвестно состояние флага прерываний или во вложенных вызовах с подобными конструкциями.

Конечно, почти всегда именно такой вариант и нужен. Особенно в виде враппера. smile.gif


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Alechin
сообщение Mar 20 2006, 15:39
Сообщение #6


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

Группа: Свой
Сообщений: 158
Регистрация: 27-06-05
Из: Химки, Моск.обл.
Пользователь №: 6 334



Запретить прерывания именно для функции (не обработчика прерывания) можно через __monitor перед именем функции. Правда тогда inline для нее выполняться не будет.
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Mar 27 2006, 09:34
Сообщение #7


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(Alechin @ Mar 20 2006, 18:39) *
Запретить прерывания именно для функции (не обработчика прерывания) можно через __monitor перед именем функции. Правда тогда inline для нее выполняться не будет.

Разве?
А если перед определением функции написать:
Код
#pragma inline=forced
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение May 29 2006, 09:42
Сообщение #8


Гуру
******

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



Дабы не плодить новых тем ещё один аналогичный вопрос... smile.gif

У меня несколько мелких прерываний и одно большое. Я хотел бы в большом разрешить прерывания (т.е. вызов маленьких). Когда я такое делал на asm, то я просто контролировал переменные/регистры. В С, если я правильно понимаю, достаточно просто разрешить прерывание __en_int. Так как при вызове используемые сохраняются в стеке. Или я не прав?
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение May 29 2006, 15:43
Сообщение #9


Гуру
******

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



Цитата(SasaVitebsk @ May 29 2006, 12:42) *
Или я не прав?


Уже вижу что не прав. В зависимости от точки вызова появляются ошибки.
Поясню подробнее, т.к. никто не ответил.

Прога. В ней два прерывания от таймера, ну и там от RS232... Одно из прерываний от таймера выполняется очень часто (регенерация экрана) и её нельзя запрещать. Во втором прерывании от таймера (выполняется на много реже) используются подпрограммы.
Как сделать что-бы "регенерация" вызывалась в ходе другого прерывания? Иными словами как данное прерывание объявить так, чтобы оно ничего не портило?

Очччччень жду ответа!
Go to the top of the page
 
+Quote Post
oleg111
сообщение May 29 2006, 16:57
Сообщение #10


Участник
*

Группа: Свой
Сообщений: 30
Регистрация: 20-01-06
Пользователь №: 13 385



Цитата(SasaVitebsk @ May 29 2006, 22:43) *
Цитата(SasaVitebsk @ May 29 2006, 12:42) *

Или я не прав?


Уже вижу что не прав. В зависимости от точки вызова появляются ошибки.
Поясню подробнее, т.к. никто не ответил.

Прога. В ней два прерывания от таймера, ну и там от RS232... Одно из прерываний от таймера выполняется очень часто (регенерация экрана) и её нельзя запрещать. Во втором прерывании от таймера (выполняется на много реже) используются подпрограммы.
Как сделать что-бы "регенерация" вызывалась в ходе другого прерывания? Иными словами как данное прерывание объявить так, чтобы оно ничего не портило?

Очччччень жду ответа!

Во втором прерывании от таймера (выполняется на много реже) используются подпрограммы - разрешить прерывания __enable_interrupt();, если прерывание от таймера может вмешатся в какойто критически важный процесс во втором прерывании то временно его запретить перед ним (процессом) , а затем разрешить опять.
Go to the top of the page
 
+Quote Post
Old1
сообщение May 29 2006, 18:58
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 697
Регистрация: 26-07-05
Из: Могилев
Пользователь №: 7 095



Цитата(SasaVitebsk @ May 29 2006, 18:43) *
Цитата(SasaVitebsk @ May 29 2006, 12:42) *

Или я не прав?


Уже вижу что не прав. В зависимости от точки вызова появляются ошибки.
Поясню подробнее, т.к. никто не ответил.

Прога. В ней два прерывания от таймера, ну и там от RS232... Одно из прерываний от таймера выполняется очень часто (регенерация экрана) и её нельзя запрещать. Во втором прерывании от таймера (выполняется на много реже) используются подпрограммы.
Как сделать что-бы "регенерация" вызывалась в ходе другого прерывания? Иными словами как данное прерывание объявить так, чтобы оно ничего не портило?

Очччччень жду ответа!

ИМХО чтобы первое прерывание (регенерация экрана) не портило второе (которое выполняется намного реже) в обработчике первого прерывания нужно сохранить в стек вспомогательные регистры. Автоматически компилятор это делает если в обработчике прерывания вызывается функция (и если компилятор ее не inlin-ит). Поэтому, если содержимое обработчика первого прерывания поместить в функцию и при входе в первое прерывание ее вызывать, то возможно портиться ничего не будет, хотя конечно прерывание обрабатываться будет существенно дольше. Это только мысли, в натуре не проверял...
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение May 29 2006, 19:47
Сообщение #12


Гуру
******

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



Цитата(Old1 @ May 29 2006, 21:58) *
ИМХО чтобы первое прерывание (регенерация экрана) не портило второе (которое выполняется намного реже) в обработчике первого прерывания нужно сохранить в стек вспомогательные регистры. Автоматически компилятор это делает если в обработчике прерывания вызывается функция (и если компилятор ее не inlin-ит). Поэтому, если содержимое обработчика первого прерывания поместить в функцию и при входе в первое прерывание ее вызывать, то возможно портиться ничего не будет, хотя конечно прерывание обрабатываться будет существенно дольше. Это только мысли, в натуре не проверял...


Я просмотрел листинг и увидел что компилятор сохраняет только 6 регистров в этом прерывании. А использует значительно больше. Вот из-за этого всё и происходит .... Варианты с запретом не прокатывают, - нельзя его запрещать.
Спасибо за совет с п/п. А может слово какое-нибудь есть "волшебное" типа "рекурсия" smile.gif чтобы компилятор всё необходимое сам сохранил?
На счёт быстродействия я пока не парюсь. Пока вроде хватает его. А в дальнейшем данное прерывание на asm напишу. Но хочу чтобы вариант на С тоже принципиально работал.
Go to the top of the page
 
+Quote Post
arttab
сообщение May 30 2006, 06:50
Сообщение #13


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

Группа: Свой
Сообщений: 1 432
Регистрация: 7-12-04
Из: Новосибирск
Пользователь №: 1 371



Не все просто с разрерением прерываний в прерывании - сам напоролся (IAR 3.10). После чего задумался о использовании для обработки некоторых событий флагов вместо прерываний


--------------------
OrCAD, Altium,IAR, AVR....
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение May 30 2006, 18:21
Сообщение #14


Гуру
******

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



Цитата(SasaVitebsk @ May 29 2006, 22:47) *
Я просмотрел листинг и увидел что компилятор сохраняет только 6 регистров в этом прерывании. А использует значительно больше. Вот из-за этого всё и происходит .... Варианты с запретом не прокатывают, - нельзя его запрещать.


Причина найдена. Не хочу никого вводить в заблуждения своими постами, поэтому описываю происходящее.
1) Компилятор ПОЛНОСТЬЮ сохраняет все используемые регистры. Поэтому при правильном написании программы можно делать вложенные прерывания простой вставкой __enable_interrupt();.
2) Ошибка происходила из-за сравнения с константой, которая была объявлена в __eeprom. Данная ошибка в работе компилятора была уже где-то описана. Я даже скачал новую версию библиотеки, любезно предоставленную, по-моему Igor Kossak (В случае ошибки прошу меня извинить). По видимому просто скачать и заменить её в каталоге было не достаточно. Может её оттранслировать необходимо было? Чтобы она в объектном виде лежала. Буду разбираться, хотя сейчас так это не ко времени.
3) Всётаки С "убивает" или "притупляет" чуство камня. Объявил в ЕЕПРОМе и работаю себе.... Фигня что не эффективно всё это... smile.gif
Придётся перелопатить прогу на предмет переноса широкоиспользуемых констант из ЕЕПРОМ в ОЗУ.

Кстати IgorKossak, если Вы увидите этот пост поясните пожалуйста как использовать Ваш файл. Я думаю многим это поможет избежать моих ошибок.

Сообщение отредактировал SasaVitebsk - May 30 2006, 18:40
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение May 31 2006, 09:30
Сообщение #15


Гуру
******

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



Что ещё настораживает, что записи у меня не было! Только чтение!
Отсюда вопрос - что за хрень???

Из прерывания1 вызывалась п/п1 она вызывала п/п2. Когда в ней в определённом месте вызывалось прерывание 2, то возникала ошибка. В месте ошибки стояла (на уровне asm) п/п чтения EEPROM.

Переполнение стеков исключено - проверял.

Конечно я как увидел обращение к EEPROM в прерывании smile.gif с претензией на скорость выполнения, то сразу убрал. И всё сразу заработало. Надо было выяснить причину. Будет побольше времени - выясню.
Go to the top of the page
 
+Quote Post

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

 


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


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