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

 
 
> как поменять адрес возврата из IRQ, нужна помощь новичку((((
lons83
сообщение Mar 1 2014, 15:17
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 69
Регистрация: 9-11-12
Пользователь №: 74 296



Здравствуйте, извините если такая тема уже повторялась. Но я никак не нашел ответа:

Есть прога:
Код
#include

func1
{
....
}

func2
{
....
}

func3
{
....
}

func4
{
....
}

IRQ   // обработчик прерывания
{
....
}

int main
{

while (1)
{


func1();

func2();

func3();

func4();

}

}



Предположим выполняется func3{} в этот момент срабатывает прерывание и передается обработчику IRQ
после завершения IRQ, программа по адресу возврата возвращается к func3{}....

НО!!!!!!

Как можно с помощью языка СИ сделать чтобы после возвращения из IRQ -> выполняться стала func1{} !!! ( поменять адрес возврата ) и уже после выполнения func1{} -> вернуться к func3{}; ??????????

Делал такое на ассмеблере, а тут как-то завис....
не понятно как в этом случае использовать ассемблерные вставки... а чтение программных прерываний ( SWI и SVC ) завели меня в тупик...

Заранее спасибо.

P.S. среда программирования Keil 4 . МК: stm cortex-m3

Сообщение отредактировал lons83 - Mar 1 2014, 15:17
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 12)
DpInRock
сообщение Mar 1 2014, 15:39
Сообщение #2


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



http://martin.hinner.info/ARM-Microcontrol...er-HOWTO-7.html


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 1 2014, 18:22
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(lons83 @ Mar 1 2014, 17:17) *
чтобы после возвращения из IRQ -> выполняться стала func1{} !!! ( поменять адрес возврата ) и уже после выполнения func1{} -> вернуться к func3{}; ??????????

Код
IRQ   // обработчик прерывания
{
....
    func1();
}

И забыть про ассемблер.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Lagman
сообщение Mar 1 2014, 18:22
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



Да, условия поменялись ...
Go to the top of the page
 
+Quote Post
lons83
сообщение Mar 1 2014, 18:35
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 69
Регистрация: 9-11-12
Пользователь №: 74 296



Цитата(Сергей Борщ @ Mar 1 2014, 22:22) *
Код
IRQ   // обработчик прерывания
{
....
    func1();
}

И забыть про ассемблер.


Можно и так... Только в этом случае Вы не выходите из прерывания. И если func1() не закончиться выполнятся до повторного входа в IRQ... то получиться рекурсия и через некоторое время контроллер зависает!!!!

Поэтому я и хочу чтобы переход был после выхода из прерывания
Go to the top of the page
 
+Quote Post
adnega
сообщение Mar 1 2014, 18:46
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(lons83 @ Mar 1 2014, 22:35) *
Можно и так... Только в этом случае Вы не выходите из прерывания. И если func1() не закончиться выполнятся до повторного входа в IRQ... то получиться рекурсия и через некоторое время контроллер зависает!!!!
Поэтому я и хочу чтобы переход был после выхода из прерывания

В Cortex-M3 есть программные прерывания. Можно установить флаг одного из них в IRQ,
но приоритет такого прерывания должен быть ниже приоритета IRQ. В обработчике программного
прерывания вызвать func1(). Тут и с пугающей рекурсией ничего не зависнет, просто будут потери вызовов
func1(). Честно говоря, станно все это, ибо вызов func1() получается асинхронным со всеми вытекающими.
Go to the top of the page
 
+Quote Post
lons83
сообщение Mar 1 2014, 19:10
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 69
Регистрация: 9-11-12
Пользователь №: 74 296



Цитата(adnega @ Mar 1 2014, 22:46) *
В Cortex-M3 есть программные прерывания. Можно установить флаг одного из них в IRQ,
но приоритет такого прерывания должен быть ниже приоритета IRQ.

Не могли бы Вы здесь по подробнее....
тогда как мне задать вектор прерывания программного для func1(); ???
Ведь аппаратные вектора все заняты, а подставить func1(); под вектор с 0-31 не получается... да и не получиться наверно...

Вообщем не понятно как указать что func1() - это программное прерывание... и как я понял оно будет вызываться из IRQ тогда зачем его делать программным?.....

Цитата(adnega @ Mar 1 2014, 22:46) *
Тут и с пугающей рекурсией ничего не зависнет, просто будут потери вызовов func1().


на практике у меня зависало... особенно если func1() --- довольно приличная функция - например обработка видео массива... и тогда все храниться в стеке и через 2 минуты забивается.... а если func1() вынести в общий цикл то все нормально работает.... просто нужно чтобы func1() запускался прямо после IRQ , а во время выполнения func1() происходит 3-4 вызова IRQ....
Go to the top of the page
 
+Quote Post
adnega
сообщение Mar 1 2014, 19:25
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(lons83 @ Mar 1 2014, 23:10) *
Не могли бы Вы здесь по подробнее....
тогда как мне задать вектор прерывания программного для func1(); ???
Ведь аппаратные вектора все заняты, а подставить func1(); под вектор с 0-31 не получается... да и не получиться наверно...
Вообщем не понятно как указать что func1() - это программное прерывание... и как я понял оно будет вызываться из IRQ тогда зачем его делать программным?.....
на практике у меня зависало... особенно если func1() --- довольно приличная функция - например обработка видео массива... и тогда все храниться в стеке и через 2 минуты забивается.... а если func1() вынести в общий цикл то все нормально работает.... просто нужно чтобы func1() запускался прямо после IRQ , а во время выполнения func1() происходит 3-4 вызова IRQ....

Аппаратный ничем не отличается от програмного. В Cortex-M3 поддерживается до 240 прерываний.
Берете свободный вектор в таблице векторов прерываний (в стартапе). Туда пишете адрес
func1() и разрешаете прерывание с выбранным номером предварительно настроив ему приоритет.
Есть хорошая книга: "Джозеф Ю. Ядро CORTEX-M3 компании ARM. Полное руководство".

Если func1() должно выполняться прямо после IRQ и IRQ вызываются в 3-4 раза чаще, чем обрабатывается func1().
То можно показать, что работать будет так:
1. Обрабатываются IRQ.
2. Только каждое 3-4 IRQ способно запустить func1().
3. Никакие func2() и т.п. выполныться не будут.

Тоже самое с успехом делает код:
while(1) func1();

Разве нет?
Go to the top of the page
 
+Quote Post
lons83
сообщение Mar 1 2014, 19:43
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 69
Регистрация: 9-11-12
Пользователь №: 74 296



Цитата(adnega @ Mar 1 2014, 23:25) *
Аппаратный ничем не отличается от програмного. В Cortex-M3 поддерживается до 240 прерываний.
Берете свободный вектор в таблице векторов прерываний (в стартапе). Туда пишете адрес
func1() и разрешаете прерывание с выбранным номером предварительно настроив ему приоритет.
Есть хорошая книга: "Джозеф Ю. Ядро CORTEX-M3 компании ARM. Полное руководство".


А можете еще раз мне обьяснить: Как произойдет вызов этого программного прерывания?
с аппаратным все понятно... а вот с программным? ведь если я помещу func1() - в обработчик - это ни чем не будет отличаться от вызова обычной функции... а если в обычном цикле программы, то тогда как? по какому то флагу?

Спасибо за книжку. Завтра скачаю и посмотрю...

Цитата(adnega @ Mar 1 2014, 23:25) *
Если func1() должно выполняться прямо после IRQ и IRQ вызываются в 3-4 раза чаще, чем обрабатывается func1().
То можно показать, что работать будет так:
1. Обрабатываются IRQ.
2. Только каждое 3-4 IRQ способно запустить func1().
3. Никакие func2() и т.п. выполныться не будут.

Тоже самое с успехом делает код:
while(1) func1();

Разве нет?


Кстати да... Вы правы... тут можно по разному это обыграть... надо подумать...
Go to the top of the page
 
+Quote Post
adnega
сообщение Mar 1 2014, 20:00
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(lons83 @ Mar 1 2014, 23:43) *
А можете еще раз мне обьяснить: Как произойдет вызов этого программного прерывания?
с аппаратным все понятно... а вот с программным? ведь если я помещу func1() - в обработчик - это ни чем не будет отличаться от вызова обычной функции... а если в обычном цикле программы, то тогда как? по какому то флагу?
Спасибо за книжку. Завтра скачаю и посмотрю...

Если с аппаратным понятно, то хорошо. Софтовый тоже самое)
Когда приходит запрос на обработку прерывания от периферийного модуля взводится флаг
отложенного прерывания в модуле NVIC.
Затем NVIC смотрит какие флаги взведены и выбирает из них один удовлетворяющий критериям
(разрешение прерывания, приоритет и т.п.). Затем переходит к обработке прерывания совершая переход
к функции, адрес которой указан в таблице векторов прерывания паралельно сбрасывая флаг отложенного
прерывания. Процесс очень хорошо описан в книге.
Таким образом Вы можете генерировать софтовые прерывания взводя флаги в NVIC.
Кроме того, Вы можете софтово запускать обработчики аппаратных прерываний.
Хуже: Вы можете снимать запрос на запуск аппаратного или софтового прерывания очищая флаг.
Короче свобода полная. Никакого asm, все на Си. Правда для запуска софтовых прерываний в непривелегированном
режиме требуется специальное на то разрешение. В книге вся инфа есть.
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Mar 2 2014, 10:36
Сообщение #11


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



ПОхоже все запутались конкретно.

До вызова прерывания выполнялась F1. После прерывания требуется выполнение F2.
ПОСЛЕ ЗАВЕРШЕНИЯ F2 - видимо, требуется продолжить F1?

Отсюда следует, что прерывание должно ЗАПОМНИТЬ контекст F1, при выходе из прерывания - заменить контекст F1 на ЗАРАНЕЕ ПОДГОТОВЛЕННЫЙ контекст F2.

И после завершения F2 - F2 - должно восстановить контекст F1.

===
Это по сути - "обычный" переключатель задач.
Это можно попытаться сделать для частного конкретного случая именно с F1 и F2.

Но по затратам кода и прочего - ничем не будет отличаться от нормального переключателя.
Ссылку на пример я приводил.

Для кортекса - у которого есть два стека, есть два режима работы процессора - можно посметреть переключать от соот. порта FreeRtos, к примеру.

Мой переключатель со всеми функциями занимает 40 строк кода на Си, и два десятка строк на ассемблере.
И это очень хорошая цена за простую многозадачность.
===============

Но правильное решение - от тов. Борща.
Если алгоритм строго детерминирован, то текст функции следует прямо вставить в обработчик.
И все страхи по поводу такого расположения должны быть исключены смыслом самого алгоритма.


Сообщение отредактировал DpInRock - Mar 2 2014, 10:48


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
ar__systems
сообщение Mar 2 2014, 16:08
Сообщение #12


self made
****

Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795



Цитата(lons83 @ Mar 1 2014, 13:35) *
Можно и так... Только в этом случае Вы не выходите из прерывания. И если func1() не закончиться выполнятся до повторного входа в IRQ... то получиться рекурсия и через некоторое время контроллер зависает!!!!

Поэтому я и хочу чтобы переход был после выхода из прерывания

Что? Какая рекурся? Повторного входа в IRQ не может быть до выхода из него.
Go to the top of the page
 
+Quote Post
Lagman
сообщение Mar 3 2014, 13:38
Сообщение #13


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



Все таки надо было оставить свой ответ в первый раз.

Смотрите в сторону RTOS, например как реализовано переключение задач в FreeRTOS.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 25th August 2025 - 00:38
Рейтинг@Mail.ru


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