|
GCC: Аварийный выход из прерывания (функции), чем заменить оператор goto? |
|
|
|
May 16 2013, 14:50
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Возникла ситуация когда при обработке прерывания нужно изменить привычный ход программы, когда содержимое сохранненых регистров и указатель стека уже не важны. Оператор goto тут не работает: Код ISR (xxx_vect) { ... ... goto m1; } void main (void) { ... ... while (1) { ... ... } m1: ... ... } Что можно здесь сделать ?
|
|
|
|
|
 |
Ответов
|
May 16 2013, 18:20
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Цитата(Lagman @ May 16 2013, 18:45)  Просто из прерывания вызываете другую функцию, зачем вам в main возвращаться, если вам не важны стэк и регистры. не могу перегружать память сохраняемыми регистрами в теме была описана ситуевина: http://electronix.ru/forum/index.php?showtopic=112377Цитата(zombi @ May 16 2013, 19:09)  Не знаю как на СИ. А на асме записываю в стек нужный мне адрес и ret на Асме я бы просто rjmp написал Цитата(Палыч @ May 16 2013, 19:40)  Функции setjmp / longjmp подойдут ? похоже нет Цитата(Палыч @ May 16 2013, 19:40)  Функции setjmp / longjmp подойдут ? похоже нет Цитата(Xenia @ May 16 2013, 20:51)  Проще всего в программе установить семафоры с ветвлением по if или switch, а из прерывания эти семафоры переключать. я так и поступил , но всеже хочется разобраться с "прыжками"
|
|
|
|
|
May 16 2013, 18:28
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(MaxiMuz @ May 16 2013, 21:20)  не могу перегружать память сохраняемыми регистрами в теме была описана ситуевина: http://electronix.ru/forum/index.php?showtopic=112377А регистры сохраняются? Вы смотрели? Цитата(MaxiMuz @ May 16 2013, 21:20)  на Асме я бы просто rjmp написал Так и напишите Код ISR(...) { asm("rjmp 0x1234"); // нужный адрес выберете сами } По выбранному адресу расположите вашу функцию (Си или асм) Цитата(MaxiMuz @ May 16 2013, 21:20)  я так и поступил , но всеже хочется разобраться с "прыжками" Изврат это какой-то, чего с ними разбираться.
|
|
|
|
|
May 19 2013, 16:27
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Цитата(Tiro @ May 18 2013, 00:26)  Метки как значения давно есть в ГСС. 4.3 Labels as Values Помоему то что нужно! Но всеже както странно , первый раз вижу оператор '&&' в таком применении. Это какаято особенность GCC стандарта ? Цитата(Xenia @ May 19 2013, 03:12)  А прыгать нельзя!  Мало ли в каком состоянии стеки находятся в том месте, откуда сигануло в прерывание? Вы, положим по метке перейдете, а стек кто чистить будет? Xenia такой сценарий  Если уж выполненно определенное условие , то стек и состояние др.регистров неважно Цитата(ARV @ May 19 2013, 09:49)  с моей точки зрения ситуация, когда "регистры и состояние стека уже не важны" должна приводить к аппаратному сбросу контроллера, и никак иначе, тем более из прерывания. Точно! программа должна выполнить определенные действия и завершиться.
Сообщение отредактировал MaxiMuz - May 19 2013, 16:27
|
|
|
|
|
May 21 2013, 20:17
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Цитата(_Артём_ @ May 20 2013, 16:31)  Мне почему-то кажется что код идущий после метки будет выкинут оптимизатором. Или нет? Вы с какими настройками компилируете? -Os нет, код после метки отстается, возможно что там используются volatile-переменные Цитата(Xenia @ May 19 2013, 22:04)  Ветвление надо произвести только один раз - в самом начале main(), еще до вхождения в бесконечный цикл. Идея с семафором, ветвлением вначале main и оригинальная, но все же я не очень доверяю сохранности портов после сброса .. Цитата Функции setjmp / longjmp подойдут ? этот вариант не подходит т.к. по сути это тот же самый вызов функции с вытекающими последствиями Цитата(ARV @ May 20 2013, 20:12)  если очень хочется, то можно вот так: Код void __attribute__((noreturn)) my_exit(void){ PORTB = 0xFF; while(1); } ISR(TIMER1_OVF_vect){ if(PINB & 1){ PORTB = 0; } else { // проблема - обрабатываем лебединую песню!!! void *ptr = my_exit; goto *ptr; } } при желании my_exit() можно вызывать и в main, не нарушая общей структуры программы. хотя с моей точки зрения это кривой костыль, правильное по моему мнению решение я озвучивал ранее. Помоему самое оптимальное решение ! т.к. даже через снятие адреса метки: Код ptr=&&m1; .... goto *ptr; компилятор заменяет на ijmp ptr что задействует еще пару регистров, которые сохраняются в стек Только неясно почему опять кривой костыль ?
|
|
|
|
|
May 21 2013, 20:54
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(MaxiMuz @ May 21 2013, 23:17)  возможно что там используются volatile-переменные Может быть. Цитата(MaxiMuz @ May 21 2013, 23:17)  но все же я не очень доверяю сохранности портов после сброса .. О каких портах речь? Входы-выходы? После сброа они будут сброшены в дефолтное состояние. Цитата(MaxiMuz @ May 21 2013, 23:17)  Помоему самое оптимальное решение ! Есть, кстати ещё вариант: в прерывании, в котором обнаружена аварийная ситуация генерить вызов другого прерывания в котором и выполнять нужные действия (уход в sleep кажется?). Программное прерывание то есть. Код ISR(TIMER1_COMPA_vect) { if (fatal_error) { // вызов программного прерывания SPMCR=1<<SPMIE; } }
ISR(SPM_RDY_vect) {
SPMCR&=~(1<<SPMIE); // действия по аварии while (1); } На запуск програмного прерывания нужно всего пара команд, поэтому дополнительных регистров не потребуется. Только сработает оно через десятков-другой тактов, но программа при этом порушена не будет.
|
|
|
|
|
May 21 2013, 21:01
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Цитата(_Артём_ @ May 21 2013, 23:54)  О каких портах речь? Входы-выходы? После сброа они будут сброшены в дефолтное состояние. тот вариант о котором говорила Xenia#17с вызовом прерывани из прерывания я тоже думал , как вариант , но всеже rjmp проще всего
|
|
|
|
Сообщений в этой теме
MaxiMuz GCC: Аварийный выход из прерывания (функции) May 16 2013, 14:50      Lagman Цитата(MaxiMuz @ May 19 2013, 20:27) Точн... May 19 2013, 18:26       Xenia Цитата(Lagman @ May 19 2013, 22:26) Если ... May 19 2013, 19:04        Палыч Цитата(Xenia @ May 19 2013, 23:04) В прер... May 20 2013, 04:53       Xenia Цитата(_Артём_ @ May 20 2013, 00:02) Если... May 19 2013, 23:31        _Артём_ Цитата(Xenia @ May 20 2013, 02:31) Тогда ... May 20 2013, 00:00        Сергей Борщ QUOTE (MaxiMuz @ May 20 2013, 15:40) а в ... May 20 2013, 13:21         Xenia Цитата(Сергей Борщ @ May 20 2013, 17:21) ... May 20 2013, 13:44          Сергей Борщ QUOTE (Xenia @ May 20 2013, 16:44) легко ... May 20 2013, 17:03           Xenia Цитата(Сергей Борщ @ May 20 2013, 21:03) ... May 20 2013, 18:41            _Артём_ Цитата(Xenia @ May 20 2013, 21:41) Нормал... May 20 2013, 19:03             Xenia Цитата(_Артём_ @ May 20 2013, 22:56) В сл... May 20 2013, 19:05              Tiro Цитата(Xenia @ May 20 2013, 22:05) Адреса... May 20 2013, 22:31             ARV Цитата(_Артём_ @ May 20 2013, 23:03) goto... May 21 2013, 18:08              _Артём_ Цитата(ARV @ May 21 2013, 21:08) так ведь... May 21 2013, 19:20            demiurg_spb Всё это (аварийный выход) стоит завернуть в какой-... May 22 2013, 06:52             Палыч Цитата(demiurg_spb @ May 22 2013, 10:52) ... May 22 2013, 07:01              demiurg_spb Цитата(Палыч @ May 22 2013, 11:01) В AVR ... May 22 2013, 07:05      Tiro Цитата(MaxiMuz @ May 19 2013, 19:27) Помо... May 19 2013, 21:32    _Артём_ Цитата(MaxiMuz @ May 17 2013, 14:10) почт... May 18 2013, 22:42  zombi Цитата(MaxiMuz @ May 16 2013, 21:20) на А... May 16 2013, 19:03  Палыч Цитата(MaxiMuz @ May 16 2013, 22:20) похо... May 16 2013, 19:40  Xenia Цитата(MaxiMuz @ May 16 2013, 22:20) я та... May 19 2013, 00:12 zombi Не знаю как на СИ.
А на асме записываю в стек нужн... May 16 2013, 16:09 Палыч Функции setjmp / longjmp подойдут ? May 16 2013, 16:40 Xenia Проще всего в программе установить семафоры с ветв... May 16 2013, 17:51 ARV Цитата(MaxiMuz @ May 16 2013, 18:50) Возн... May 19 2013, 06:49 ARV если очень хочется, то можно вот так:Кодvoid __at... May 20 2013, 17:12 Сергей Борщ _Артем_ ответил по всем пунктам.
Касаемо последних... May 21 2013, 07:45 Палыч Совершенно непонятно: почему ТС не хочет использов... May 21 2013, 08:00  _Артём_ Цитата(Палыч @ May 21 2013, 11:00) Соверш... May 21 2013, 12:51 rudy_b Что-то непонятно. Что значит "программа должн... May 21 2013, 19:32 _Артём_ Цитата(rudy_b @ May 21 2013, 22:32) И что... May 21 2013, 19:47  rudy_b Цитата(_Артём_ @ May 21 2013, 22:47) Пере... May 22 2013, 08:28   MaxiMuz Цитата(rudy_b @ May 22 2013, 11:28) А что... May 25 2013, 06:49 _Pasha Пора голосовать, хто за setjmp/longjmp ? May 25 2013, 10:16
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|