|
|
  |
Запрет прерываний при вызове функций, и их разрешение |
|
|
|
Mar 13 2006, 06:56
|

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().
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Mar 27 2006, 09:34
|

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

|
Цитата(Alechin @ Mar 20 2006, 18:39)  Запретить прерывания именно для функции (не обработчика прерывания) можно через __monitor перед именем функции. Правда тогда inline для нее выполняться не будет. Разве? А если перед определением функции написать: Код #pragma inline=forced
|
|
|
|
|
May 29 2006, 15:43
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(SasaVitebsk @ May 29 2006, 12:42)  Или я не прав? Уже вижу что не прав. В зависимости от точки вызова появляются ошибки. Поясню подробнее, т.к. никто не ответил. Прога. В ней два прерывания от таймера, ну и там от RS232... Одно из прерываний от таймера выполняется очень часто (регенерация экрана) и её нельзя запрещать. Во втором прерывании от таймера (выполняется на много реже) используются подпрограммы. Как сделать что-бы "регенерация" вызывалась в ходе другого прерывания? Иными словами как данное прерывание объявить так, чтобы оно ничего не портило? Очччччень жду ответа!
|
|
|
|
|
May 29 2006, 16:57
|
Участник

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

|
Цитата(SasaVitebsk @ May 29 2006, 22:43)  Цитата(SasaVitebsk @ May 29 2006, 12:42)  Или я не прав?
Уже вижу что не прав. В зависимости от точки вызова появляются ошибки. Поясню подробнее, т.к. никто не ответил. Прога. В ней два прерывания от таймера, ну и там от RS232... Одно из прерываний от таймера выполняется очень часто (регенерация экрана) и её нельзя запрещать. Во втором прерывании от таймера (выполняется на много реже) используются подпрограммы. Как сделать что-бы "регенерация" вызывалась в ходе другого прерывания? Иными словами как данное прерывание объявить так, чтобы оно ничего не портило? Очччччень жду ответа! Во втором прерывании от таймера (выполняется на много реже) используются подпрограммы - разрешить прерывания __enable_interrupt();, если прерывание от таймера может вмешатся в какойто критически важный процесс во втором прерывании то временно его запретить перед ним (процессом) , а затем разрешить опять.
|
|
|
|
|
May 29 2006, 18:58
|

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

|
Цитата(SasaVitebsk @ May 29 2006, 18:43)  Цитата(SasaVitebsk @ May 29 2006, 12:42)  Или я не прав?
Уже вижу что не прав. В зависимости от точки вызова появляются ошибки. Поясню подробнее, т.к. никто не ответил. Прога. В ней два прерывания от таймера, ну и там от RS232... Одно из прерываний от таймера выполняется очень часто (регенерация экрана) и её нельзя запрещать. Во втором прерывании от таймера (выполняется на много реже) используются подпрограммы. Как сделать что-бы "регенерация" вызывалась в ходе другого прерывания? Иными словами как данное прерывание объявить так, чтобы оно ничего не портило? Очччччень жду ответа! ИМХО чтобы первое прерывание (регенерация экрана) не портило второе (которое выполняется намного реже) в обработчике первого прерывания нужно сохранить в стек вспомогательные регистры. Автоматически компилятор это делает если в обработчике прерывания вызывается функция (и если компилятор ее не inlin-ит). Поэтому, если содержимое обработчика первого прерывания поместить в функцию и при входе в первое прерывание ее вызывать, то возможно портиться ничего не будет, хотя конечно прерывание обрабатываться будет существенно дольше. Это только мысли, в натуре не проверял...
|
|
|
|
|
May 29 2006, 19:47
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Old1 @ May 29 2006, 21:58)  ИМХО чтобы первое прерывание (регенерация экрана) не портило второе (которое выполняется намного реже) в обработчике первого прерывания нужно сохранить в стек вспомогательные регистры. Автоматически компилятор это делает если в обработчике прерывания вызывается функция (и если компилятор ее не inlin-ит). Поэтому, если содержимое обработчика первого прерывания поместить в функцию и при входе в первое прерывание ее вызывать, то возможно портиться ничего не будет, хотя конечно прерывание обрабатываться будет существенно дольше. Это только мысли, в натуре не проверял... Я просмотрел листинг и увидел что компилятор сохраняет только 6 регистров в этом прерывании. А использует значительно больше. Вот из-за этого всё и происходит .... Варианты с запретом не прокатывают, - нельзя его запрещать. Спасибо за совет с п/п. А может слово какое-нибудь есть "волшебное" типа "рекурсия"  чтобы компилятор всё необходимое сам сохранил? На счёт быстродействия я пока не парюсь. Пока вроде хватает его. А в дальнейшем данное прерывание на asm напишу. Но хочу чтобы вариант на С тоже принципиально работал.
|
|
|
|
|
May 30 2006, 18:21
|
Гуру
     
Группа: Свой
Сообщений: 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) Всётаки С "убивает" или "притупляет" чуство камня. Объявил в ЕЕПРОМе и работаю себе.... Фигня что не эффективно всё это... Придётся перелопатить прогу на предмет переноса широкоиспользуемых констант из ЕЕПРОМ в ОЗУ. Кстати IgorKossak, если Вы увидите этот пост поясните пожалуйста как использовать Ваш файл. Я думаю многим это поможет избежать моих ошибок.
Сообщение отредактировал SasaVitebsk - May 30 2006, 18:40
|
|
|
|
|
May 31 2006, 09:30
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Что ещё настораживает, что записи у меня не было! Только чтение! Отсюда вопрос - что за хрень??? Из прерывания1 вызывалась п/п1 она вызывала п/п2. Когда в ней в определённом месте вызывалось прерывание 2, то возникала ошибка. В месте ошибки стояла (на уровне asm) п/п чтения EEPROM. Переполнение стеков исключено - проверял. Конечно я как увидел обращение к EEPROM в прерывании  с претензией на скорость выполнения, то сразу убрал. И всё сразу заработало. Надо было выяснить причину. Будет побольше времени - выясню.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|