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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Выход из прерывания в требуемую точку
VslavX
сообщение May 17 2011, 19:10
Сообщение #16


embarrassed systems engineer
*****

Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038



Цитата(aaarrr @ May 17 2011, 19:19) *
Ну, хоть бы пример привели, а то так не интересно.

У меня есть такой случай, при котором надо сбросить контекст прерывания и выйти в конкретную точку.
АЦП работает обычно в режиме free-running, один из каналов следит за внешним питающим напряжением (часто там аккумулятор). Непрерывный анализ этого напряжения производится в прерывании. Можно было бы отдельную высокоприоритетную задачу завести, но жаль времени на постоянное переключение контекста и место под стек, к тому же там есть ряд нюансов с критическими секциями. И вот когда это напряжение становится ниже порога и нет критической секции, то надо выключить всех потребителей и перевести изделие в режим микропотребления. При этом RTOS уже не нужна - работает специальная процедура - вот тут то и потребовалось сделать возврат из прерывания в особую точку. Еще вариант - критическая ошибка в прерывании, когда надо выдать аналог BSOD - тут тоже желательно выйти (для некоторых архитектур) из режима прерывания. Ну а вообще, да - осознанный возврат "налево" при штатной работе (особенно если еще есть RTOS) то как бы "не камильфо". Нужно только в критических случаях, RTOS после этого уже не живет, а изделие в целом выходит в останов/спячку.

Go to the top of the page
 
+Quote Post
paskal
сообщение May 17 2011, 19:14
Сообщение #17


Местный
***

Группа: Свой
Сообщений: 352
Регистрация: 29-10-06
Из: Тула
Пользователь №: 21 769



Цитата(ReAl @ May 17 2011, 22:51) *
Что-то мне кажется, что от возникновения прерывания до начала работы реального обработчика это будет быстрее, чем занесение в стек дополнительного адреса возврата для «возврата» в некий процесс.

Напомню что пример был по обработке сложного протокола с большим количеством вариантов. Переход по адресу хоть и требует дополнительных действий, но происходит СРАЗУ в нужное место. А альтернатива этому методу - долго лазить по дереву state_machine с помощью флагов и ветвлений.

Цитата(KnightIgor @ May 17 2011, 22:55) *
Что Вы тут описали, это одна из возможных реализаций state machine - давно известная и наглядная штука для ветвлящихся алгоритмов.

Конечно известная. Речь не о стэйтмашине вообще, а о том что реализовать ее можно либо адресами переходов, либо набором флагов и переменных состояния с последующими ветвлениями по этим флагам. И первый способ и нагляднее и быстрее.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение May 17 2011, 20:04
Сообщение #18


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(paskal @ May 18 2011, 01:14) *
Конечно известная. Речь не о стэйтмашине вообще, а о том что реализовать ее можно либо адресами переходов, либо набором флагов и переменных состояния с последующими ветвлениями по этим флагам. И первый способ и нагляднее и быстрее.

Дело в том, что вызов функции - это тоже "переход по адресу":) И вместо "адреса перехода" вы можете хранить в переменной "адрес функции", соответствующей текущему состоянию. О чём вам и написал ReAl.
Разница же между "вызовом функции"(он же "переход по адресу") и "подменой адреса возврата из прерывания", о которой спрашивал топикстартер, заключается в том, что во втором случае перед переходом по адресу происходит окончание прерывания. Вопрос в том, нужно ли это топикстартеру, и что ему это даст. В 8051 это давало разрешение прерываний (о чём написал я). А в кортексах - не даёт ничего. (Вернее, кое что конечно меняется, но не так радикально).


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ReAl
сообщение May 17 2011, 21:09
Сообщение #19


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Krom @ May 17 2011, 16:48) *
; сохраняем регистр прерываний
push IE
; запрещаем прерывания
clr EA
; берем требуемый адрес
mov DPTR,#PROCESS
; подсовываем в стек
push DPH
push DPL
; и выходим куда нужно
reti
Кстати, если уж на то пошло, именно в таком варианте (с одной конкретной «подпрограммой завершения», в стек заносится фиксированный адрес) на 51-ых это решалось короче:
Код
tf0_isr:
    _push <PSW, ACC, AR0>
    ...
    breq @@PROCESS; ну к примеру так решили, что надо проджолжать на низком приоритете
    _pop <AR0, ACC, PSW>
@@reti:  ; в очередной раз спасибо VslavX за утилтику «локальных меток»
    reti

@@PROCESS:
    acall @@reti
   ; а вот тут и начинается код того PROCESS -- тут уже уровень прерывания очищен
   ; выполнение продолжается на уровне приоритета основной программы
    ...
    ...
    _pop <AR0, ACC, PSW>
    ret
Т.е. вместо занесения в DPTR константы и заталкивания её в стек (или через аккумулятор -- на байт длиннее, но не нужно DPTR трогать) -- одна команда acall.
reti есть что там, что там. Помнить про пушнутое и попать его -- тоже.

Цитата(VslavX @ May 17 2011, 22:10) *
При этом RTOS уже не нужна - работает специальная процедура - вот тут то и потребовалось сделать возврат из прерывания в особую точку.
Знакомо, хотя и с «суперциклом», а не с нормальной ОС.
Один из тех исключительных случаев, когда это действительно нужно.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Krom
сообщение May 18 2011, 05:15
Сообщение #20


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

Группа: Свой
Сообщений: 107
Регистрация: 27-06-05
Из: Россия
Пользователь №: 6 324



Цитата(aaarrr @ May 17 2011, 20:19) *
Ну, хоть бы пример привели, а то так не интересно.

Пример: прерывание UART принимает пакет определенного формата (скажем, команду устройству, которая должна выполняться в фоновом режиме), которая должна быть обработана. Команда может выполняться долго, и обрабатываеть ее прямо в прерывании скажем так - не комильфо.
Go to the top of the page
 
+Quote Post
scifi
сообщение May 18 2011, 05:22
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Krom @ May 18 2011, 09:15) *
Пример: прерывание UART принимает пакет определенного формата (скажем, команду устройству, которая должна выполняться в фоновом режиме), которая должна быть обработана. Команда может выполняться долго, и обрабатываеть ее прямо в прерывании скажем так - не комильфо.

Некрасиво обрабатывать команды в прерывании. Обычно в прерывании реализуют приёмный буфер, а разбор и обработку команды - в главном цикле (это если без ОС) или в отдельном потоке (с ОС). А фокусы с модификацией адреса возврата и прочее - это излишняя экзотика.
Go to the top of the page
 
+Quote Post
Krom
сообщение May 18 2011, 05:26
Сообщение #22


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

Группа: Свой
Сообщений: 107
Регистрация: 27-06-05
Из: Россия
Пользователь №: 6 324



Цитата(AHTOXA @ May 17 2011, 21:11) *
практически полностью эквивалентен варианту "в конце прерывания вызвать нужную функцию".

В моем варианте это не подходит. Команды могут выполняться подолгу, до нескольких секунд, а прерывание UART должно жить и отвечать мастеру, что в случае выполнения обработки этой команды в прерывании невозможно.
Go to the top of the page
 
+Quote Post
scifi
сообщение May 18 2011, 05:30
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Krom @ May 18 2011, 09:26) *
Команды могут выполняться подолгу, до нескольких секунд, а прерывание UART должно жить и отвечать мастеру, что в случае выполнения обработки этой команды в прерывании невозможно.

В таком случае RTOS очень помогла бы. Ну а без RTOS напрашивается использование прерываний для обработки команд, причём приоритеты прерываний соответствуют приоритетам команд.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение May 18 2011, 05:34
Сообщение #24


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Krom @ May 18 2011, 08:15) *
Пример: прерывание UART принимает пакет определенного формата (скажем, команду устройству, которая должна выполняться в фоновом режиме), которая должна быть обработана. Команда может выполняться долго, и обрабатываеть ее прямо в прерывании скажем так - не комильфо.

Это Вы основной цикл слишком медленным сделали. Даже без РТОС можно создать приоритеты для вызываемых подзадач, и ситуёвина улучшится в разы. Приоритеты как раз могут изменяться внутри прерывания.

Сообщение отредактировал _Pasha - May 18 2011, 05:35
Go to the top of the page
 
+Quote Post
Krom
сообщение May 18 2011, 05:47
Сообщение #25


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

Группа: Свой
Сообщений: 107
Регистрация: 27-06-05
Из: Россия
Пользователь №: 6 324



Цитата(scifi @ May 18 2011, 09:22) *
Некрасиво обрабатывать команды в прерывании. Обычно в прерывании реализуют приёмный буфер, а разбор и обработку команды - в главном цикле (это если без ОС) или в отдельном потоке (с ОС). А фокусы с модификацией адреса возврата и прочее - это излишняя экзотика.

ОСи нет, а главный цикл очень сложный, с вводами с клавиатуры и т.д., и когда дойдет очередь до обработки команды - хз. В 51х все работало на ура, и здесь будет wink.gif, просто нигде не могу найти детального описания - что происходит при передаче управления обработчику прерывания и при выходе из него. Например, в поисании указано, что при передаче управления обработчику прерывания в стек автоматически помещается 8 регистров: R0-R3,LR,PC,xPSR. Смотрю в листингах:
При входе в обработчик SysTick:
64:M1504/lpc17xx_it.c **** void SysTick_Handler(void)
65:M1504/lpc17xx_it.c **** {
200 .loc 1 65 0
201 .cfi_startproc
202 @ args = 0, pretend = 0, frame = 0
203 @ frame_needed = 1, uses_anonymous_args = 0
204 @ link register save eliminated.
205 0000 80B4 push {r7}
206 .LCFI14:
207 .cfi_def_cfa_offset 4
208 .cfi_offset 7, -4
209 0002 00AF add r7, sp, #0

При выходе:
248 .loc 1 74 0
249 0068 BD46 mov sp, r7
250 006a 80BC pop {r7}
251 006c 7047 bx lr
252 .cfi_endproc


Нигде нет обработки этих самых 8 регистров в стеке. Они отрабатываюся автомачически самим контроллером или? Мне бы мануал детальный найти...



Go to the top of the page
 
+Quote Post
scifi
сообщение May 18 2011, 06:17
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Krom @ May 18 2011, 09:47) *
а главный цикл очень сложный, с вводами с клавиатуры и т.д., и когда дойдет очередь до обработки команды - хз

Вот это и есть корень проблемы. И костыли с подменой адреса возврата из прерывания не сильно помогут, IMHO.

Цитата(Krom @ May 18 2011, 09:47) *
В 51х все работало на ура, и здесь будет wink.gif

А что же сподвигло уйти от 51-го?
Cortex тем и хорош, что с ним не нужны все эти уловки, чтобы выжать последние соки из хилого процессора. Для Cortex можно программировать на нормальном Си, ведь это нормальный 32-разрядный процессор с приличной производительностью. Переносить на него грязные хаки из 51-го выглядит неприличным.

Цитата(Krom @ May 18 2011, 09:47) *
Мне бы мануал детальный найти...

Гугл пробовали?
cortex-m3 manual
Go to the top of the page
 
+Quote Post
Krom
сообщение May 18 2011, 06:50
Сообщение #27


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

Группа: Свой
Сообщений: 107
Регистрация: 27-06-05
Из: Россия
Пользователь №: 6 324



Цитата(scifi @ May 18 2011, 10:17) *
И костыли с подменой адреса

Ну так и сразу костыли... Программерский трюк это не костыль wink.gif. В любом боле-менее сносном программно-аппаратном комплексе защиты ПО таких "костылей" тьма-тьмущая, и без них вообще никак, так что-же?
Цитата(scifi @ May 18 2011, 10:17) *
А что же сподвигло уйти от 51-го?

Ну я не это предлагал обсудить...
Цитата(scifi @ May 18 2011, 10:17) *
Переносить на него грязные хаки из 51-го выглядит неприличным.

Грязные? Хаки? Чем они грязные и почему хаки?
Цитата(scifi @ May 18 2011, 10:17) *
Гугл пробовали?

Пробовал. Хотелось бы найти хорошую диаграммку с детальным описанием, как в мануале Филипса для 51х контроллеров. А то что в гугле по Кортексам разобраться конечно можно, но проштудировав много-много разных мануалов. Просто вопрос времени. Ведь мог кто-то уже сталкиваться с подобной задачей и решить ее? Мог. Почему бы мне не спросить? Вроде для того и форум.
Go to the top of the page
 
+Quote Post
Александр_С
сообщение May 18 2011, 07:01
Сообщение #28


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 18-03-08
Пользователь №: 36 026



Переключаться на другую задачю всегда надо через PendSV_Handler, так как прерывания могут быть вложеные.
Go to the top of the page
 
+Quote Post
Krom
сообщение May 18 2011, 07:14
Сообщение #29


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

Группа: Свой
Сообщений: 107
Регистрация: 27-06-05
Из: Россия
Пользователь №: 6 324



Цитата(Александр_С @ May 18 2011, 11:01) *
Переключаться на другую задачю всегда надо через PendSV_Handler, так как прерывания могут быть вложеные.

Я за советом и обратился sm.gif Задача собственно в том и стоит, чтобы по определенному событию (получен пакет с командой) как-то переключится на обработчик этой команды (может, программное прерывание?), а уж потом из обработчика вернуться туда, откуда попали в прерывание. Вероятно, я не совсем точно сформулировал проблему, сорри...
Go to the top of the page
 
+Quote Post
Александр_С
сообщение May 18 2011, 07:15
Сообщение #30


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 18-03-08
Пользователь №: 36 026



//Формирование прерывания "PendSV_Handler"
*(volatile unsigned *)0xE000ED04 = 0x10000000;
Go to the top of the page
 
+Quote Post

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

 


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


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