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

 
 
> Понижение приоритета прерывания "на лету"?, Выход из прерывания без выхода из него.
KnightIgor
сообщение Feb 23 2011, 14:08
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Добрый день!

Предположим, имеется прерывание высокого приоритета. ISR (процедура обработки прерывания), обслужив быстренько себя (например, установив/сбросив флаги), должна затем запустить некоторый процесс. Запуск процесса предполагает каждый раз некую инициализацию, которая длится долго (например, расчеты). Таким образом, если вызвать процедуру запуска процесса непосредственно из ISR, то это будет блокировать всю систему. Конечно, можно установить в ISR лишь некий флажок, проанализировать его в синхронном цикле программы и оттуда запустить процесс. Идея, однако, в том, чтобы еще внутри ISR как бы сделать вид, что ISR завершена, и спокойно вызвать процедуру:

Код
void xxx_IRQn(void) {

// быстрое и короткое действие самообслуживания
..
// понижение "приоритета" до уровня основной программы
..
// вызов длительного действия, которое может быть прервано другими ISR
  InitSomeProcess();

// выход из ISR
..
}

Для тех, кто имел дело с 51-ми процессорами, там был такой трюк: в ISR можно вызвать (call) инструкцию RETI, что приводило к "переводу" системы на уровень приоритета основной программы, после чего выполнять действия, которые могли уже быть прерваны иными ISR:

Код
void  xxx_Vector(void)   interrupt INTERRUPT_XXXX

// быстрое и короткое действие самообслуживания
..
// понижение "приоритета" до уровня основной программы
  call _RETI

// вызов длительного действия, которое может быть прервано другими ISR
  InitSomeProcess();

// выход из ISR
_RETI: RETI
}


Предполагаю, что где-то надо покрутиться с NVIC. Но не соображу пока, как.

P.S. Извините, если разжевываю вопрос как для "чайников": зачастую читаю тут вопросы и не могу врубиться, а что же спрашивают и куда хотят. Кому все сразу понятно, читайте через строку wink.gif.

TIA
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
GetSmart
сообщение Feb 23 2011, 16:03
Сообщение #2


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Да ладно. Я читал о контроллере прерываний ядра Кортекс-М.
Может быть задействовано 68. Остальные не подключены к периферии, но программно вызываются.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Feb 24 2011, 09:42
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(GetSmart @ Feb 23 2011, 17:03) *
Да ладно. Я читал о контроллере прерываний ядра Кортекс-М.
Может быть задействовано 68. Остальные не подключены к периферии, но программно вызываются.

Проверил на железе (STM32F103RB): к сожалению, НЕ вызываются, точнее - вообще не разрешаются прерывания.
В указаном процессоре максимальный номер IRQn = 42 (в отладчике - KEIL - максимальный индекс 42+16=58). Я попробовал разместить вектор как IRQn = 43 (расширил Startup). Код размещается, все путем (почти - ниже расскажу, что странно). Однако при попытке разрешить прерывание (записать соответствующий бит в нужный регистр NVIC_ISERx) бит НЕ хочет устанавливаться, ни программно (ассемблер смотрел), ни напрямую (в окне отображения содержимого памяти в отладчике). То есть, такое впечатление, что само железо затянуло бит на "0", и всё. Соответственно, запись NVIC->STIR = 43 ничего не вызывает. Вот если подготовить и дернуть таким образом IRQn из существующих (< 43), то да, работает. Такие дела...

Теперь о странностях размещения кода.
Например, берем обработчик прерывания от, скажем, USART1. Компилируем, смотрим карту памяти (*.MAP). Видим:

USART1_IRQHandler 0x08000f47 Thumb Code 164 serial.o(.text)

Смотрим содержимое таблицы векторов (память под отладчиком, секция RESET, начиная с 0x08000000). По адресу 0x080000D4 (USART1_IRQn = 37, то есть по адресу 0x08000000+4*(37.+ 16.)) и правда видим:

0x080000D4: 47 0F 00 08 ...

Идем в текст программы, ставим точку останова на USART1_IRQHandler, запускаем, дожидаемся, когда щелкнет, смотрим и видим...

0x08000F46 B5 10 push {r4, lr}

Обратите внимание, что адрес на единицу меньше значения в таблице векторов и карте памяти! Это как? Жук KEIL'а?

Сообщение отредактировал KnightIgor - Feb 24 2011, 09:45
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- KnightIgor   Понижение приоритета прерывания "на лету"?   Feb 23 2011, 14:08
- - _dem   А зачем так извращаться ? В конце концов, если та...   Feb 23 2011, 14:11
- - scifi   По-моему, описанное достигается очень просто: для ...   Feb 23 2011, 14:14
- - GetSmart   Для этих целей существуют софтовые прерывания. Им ...   Feb 23 2011, 14:24
|- - KnightIgor   Цитата(GetSmart @ Feb 23 2011, 15:24) Для...   Feb 23 2011, 14:58
- - GetSmart   В кортексах минимум 240 прерываний IRQ. обычно пер...   Feb 23 2011, 15:06
|- - scifi   Цитата(GetSmart @ Feb 23 2011, 18:06) В к...   Feb 23 2011, 15:45
|- - scifi   Цитата(GetSmart @ Feb 23 2011, 19:03) Мож...   Feb 23 2011, 16:44
|- - scifi   Цитата(KnightIgor @ Feb 24 2011, 12:42) О...   Feb 24 2011, 09:50
- - AlexandrY   Цитата(KnightIgor @ Feb 23 2011, 16:08) П...   Feb 23 2011, 17:35
|- - KnightIgor   Цитата(AlexandrY @ Feb 23 2011, 18:35) Эт...   Feb 23 2011, 20:57
|- - Aaron   Цитата(KnightIgor @ Feb 23 2011, 23:57) А...   Feb 24 2011, 07:21
- - GetSmart   KnightIgor, с нечётными адресами всё так и должно ...   Feb 24 2011, 11:27
|- - KnightIgor   Цитата(GetSmart @ Feb 24 2011, 12:27) Kni...   Feb 24 2011, 11:38
- - GetSmart   Небольшое продолжение темы. Регистр NVIC->STIR ...   Jul 4 2013, 12:33


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

 


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


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