|
Переход из прерывания |
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 22)
|
Feb 20 2006, 13:21
|
Местный
  
Группа: Свой
Сообщений: 269
Регистрация: 17-11-05
Из: Киров-Москва
Пользователь №: 10 957

|
Цитата это делается просто: в прерывании модифицируется флажок типа volatile, а в основном цикле программы он проверяется Это не подходит. Цитата Точно так же - напишите низкоуровневую функцию манипуляции контекстами на асме, а вызывайте ее из С То есть без асма не обойтись? Весь проблем, как из асма перейти к метке внутри функции main.? Как сделать метку видимой для других? Уточню свою задачу. Функция чтения в цикле опрашивает порт. Если через какое то время порт не ответил, функция должна передать управление в начало программы, но не в самое начало, а туда , где начальные условия уже выставлены и необходимо попытаться реанимировать устройство, подключенное к порту, отправив ему сброс. Пока применяю WDT, но он делает полный сброс, к устройствам, подключенным к порту, проходят броски.
Сообщение отредактировал Георгий - Feb 20 2006, 13:30
--------------------
Обычно последним смеется тот, кто хуже соображает!
|
|
|
|
|
Feb 21 2006, 12:05
|

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

|
Цитата(Георгий @ Feb 21 2006, 17:27)  Дело в том, что после сброса устройства, программа должна начать все практически сначала. Если бы можно ограничиться функцией, так бы и сделал. Нужен именно переход в начало программы, но не в самое. Непонятно, откуда такое суровое требование - обнулять работу программы при отсутствии сигнала в каком-то порте. Да еще и не совсем обнулять, а частично. Неужели нельзя как-то штатно эту ситуацию обрабатывать? Ну нет сигнала - это, да, событие, которое трубует обработки (как и многие другие события в системе). Зачем работу программы-то рушить? Целостность работы нарушать...
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Feb 21 2006, 12:24
|
Местный
  
Группа: Свой
Сообщений: 269
Регистрация: 17-11-05
Из: Киров-Москва
Пользователь №: 10 957

|
Вся работа программы зависит от ответа устройства, опрос его может быть из разных мест, если после каждого вызова каждой функции проверять флаг, а потом делать многоуровневый откат к началу программы, это тоже не выход. Устройство может быть выдернуто в любой момент, и обнаружение ведется по прерыванию, это нормально. Но уходить надо в определенную точку из прерывания. Я не совсем еще понимаю логику работы ИАРа, но, наверно, как то можно подменить адрес возврата из прерывания на адрес этой точки. Может longjmp это и делает?
--------------------
Обычно последним смеется тот, кто хуже соображает!
|
|
|
|
|
Feb 21 2006, 13:15
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата(Георгий @ Feb 21 2006, 14:24)  Вся работа программы зависит от ответа устройства, опрос его может быть из разных мест, если после каждого вызова каждой функции проверять флаг, а потом делать многоуровневый откат к началу программы, это тоже не выход. Устройство может быть выдернуто в любой момент, и обнаружение ведется по прерыванию, это нормально. Но уходить надо в определенную точку из прерывания. Я не совсем еще понимаю логику работы ИАРа, но, наверно, как то можно подменить адрес возврата из прерывания на адрес этой точки. Может longjmp это и делает? setjmp запоминает в jmpbuf все необходимые регистры (в том числе Y, SP, PC) в точке вызова этой функции. longjmp все это загружает обратно и возвращается по записанному в jmpbuf PC. Т.е. то, что надо.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Feb 21 2006, 13:19
|

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

|
Цитата(Георгий @ Feb 21 2006, 18:24)  Вся работа программы зависит от ответа устройства, опрос его может быть из разных мест, если после каждого вызова каждой функции проверять флаг, а потом делать многоуровневый откат к началу программы, это тоже не выход. Устройство может быть выдернуто в любой момент, и обнаружение ведется по прерыванию, это нормально. Но уходить надо в определенную точку из прерывания. Ну и зачем делать откат в начало? Пусть себе программа работает, если выдернули устройство, то программа переходит в один режим, если вставили, то в другой. Зачем что-то обнулять? Заведите переменную, обозначающую режим и проверяйте ее. Вот прикинье - вставили/вынули USB дивайс, винда перегрузилась - хорошо это?  Цитата(Георгий @ Feb 21 2006, 18:24)  Я не совсем еще понимаю логику работы ИАРа, но, наверно, как то можно подменить адрес возврата из прерывания на адрес этой точки. Может longjmp это и делает? Логики IAR'а тут никакой нет - он действует в рамках Стандарта языков С/С++. longjmp действительно может реализовать такое, но все-таки, имхо, это не путь. Имхо, чего-то не того в дизайне проги. Вы бы чуть подробнее изложили преметную область, может чего и посоветовать удалось бы.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Feb 21 2006, 13:43
|
Местный
  
Группа: Свой
Сообщений: 269
Регистрация: 17-11-05
Из: Киров-Москва
Пользователь №: 10 957

|
Что то инет у меня глючит, начинаю отвечать , отрубается. Транслировать наверх получется сложнее, чем сделать один переход из одной функции прерывания. Функций чтения много, и они могут быть и на втором и на третьем уровне. Это сколько проверо по дороге надо делать. Цитата Ну и зачем делать откат в начало? Пусть себе программа работает, если выдернули устройство, то программа переходит в один режим, если вставили, то в другой. Зачем что-то обнулять? Заведите переменную, обозначающую режим и проверяйте ее. Вот прикинье - вставили/вынули USB дивайс, винда перегрузилась - хорошо это? Тут больше аналогия с другим просится - если выдернуть системный винт, то чем винде еще заниматься, как не перезагружаться в цикле и определять подключен винт или нет.
--------------------
Обычно последним смеется тот, кто хуже соображает!
|
|
|
|
|
Feb 21 2006, 14:05
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Георгий @ Feb 21 2006, 15:52)  Поправляюсь - функция чтения естественно одна. Но вызываеться она может с разных уровней. мало ли откуда она вызывается? главное чтобы функция чтения производила разбор протокола работы с устройством, и обрабатывала ошибки связи, а на верхний уровень передавала только правильно распознанные данные. Цитата Но отсутствие устройства все рано определяется возникновением прерывания, и логично из него уйти в начало. Этим сейчас WDT занимается, но он делает полный сброс. В прерывании установить флаг ошибки устройства, который заблокирует например функцию чтения. Разблокировать этот флаг может например, функция "реанимации" устройства, которая будет вызываться пока флаг ошибки устройства установлен.
|
|
|
|
|
Feb 21 2006, 14:19
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Георгий @ Feb 21 2006, 16:11)  Нет, уж я лучше оставлю все как есть. вероятно, это правильное решение. WDT всяко надежнее манипуляций со стеком и неправильного использования прерываний. Цитата Иначе из-за одного перехода придется переписывать всю программу, менять все функции на булевые, чтобы корректно откатываться наверх. У меня эта прога была сначала написана на ассемблере, и там переход из прерывания в начало программы решал все проблемы. А перевел на Си и столкнулся с этой бякой. Менять пришлось бы только функцию чтения...
|
|
|
|
|
Feb 22 2006, 05:08
|
Местный
  
Группа: Свой
Сообщений: 269
Регистрация: 17-11-05
Из: Киров-Москва
Пользователь №: 10 957

|
Цитата Менять пришлось бы только функцию чтения... И все вызывающие ее функции. Они тоже должны вернуть наверх ошибку. Вечером дома посидел, подумал. Наверно, так оно и следует делать в о общем случае. (По крайней мере, когда пишу драйвера, там сплошь проверки условий и возврат булева результата). Но когда пишешь супер компактный код, приходится жертвовать некоторыми принципами. "Правильная" проверка флагов и откат по ошибке наверх увеличили программу почти на 200 байт. И глубина стека возросла. Вариант с longjmp тоже оказался не походящим - jmp_buf отъедает 21 байт от ОЗУ (из 128). На стек уже не остается.
Сообщение отредактировал Георгий - Feb 22 2006, 09:06
--------------------
Обычно последним смеется тот, кто хуже соображает!
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|