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

 
 
> GCC: Аварийный выход из прерывания (функции), чем заменить оператор goto?
MaxiMuz
сообщение May 16 2013, 14:50
Сообщение #1


Местный
***

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



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

Что можно здесь сделать ?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Lagman
сообщение May 16 2013, 15:45
Сообщение #2


Знающий
****

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



Просто из прерывания вызываете другую функцию, зачем вам в main возвращаться, если вам не важны стэк и регистры.
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение May 16 2013, 18:20
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 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, а из прерывания эти семафоры переключать.
я так и поступил , но всеже хочется разобраться с "прыжками"
Go to the top of the page
 
+Quote Post
_Артём_
сообщение May 16 2013, 18:28
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 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) *
я так и поступил , но всеже хочется разобраться с "прыжками"

Изврат это какой-то, чего с ними разбираться.
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение May 17 2013, 11:10
Сообщение #5


Местный
***

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



Цитата(_Артём_ @ May 16 2013, 21:28) *
А регистры сохраняются? Вы смотрели?
почти все старшие регистры, независимо используются они или нет
Go to the top of the page
 
+Quote Post
Tiro
сообщение May 17 2013, 21:26
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 781
Регистрация: 3-10-04
Из: Санкт-Петербург
Пользователь №: 768



Цитата(MaxiMuz @ May 17 2013, 14:10) *
почти все старшие регистры, независимо используются они или нет

Метки как значения давно есть в ГСС. 4.3 Labels as Values
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение May 19 2013, 16:27
Сообщение #7


Местный
***

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



Цитата(Tiro @ May 18 2013, 00:26) *
Метки как значения давно есть в ГСС. 4.3 Labels as Values

Помоему то что нужно!
Но всеже както странно , первый раз вижу оператор '&&' в таком применении. Это какаято особенность GCC стандарта ?

Цитата(Xenia @ May 19 2013, 03:12) *
А прыгать нельзя! sm.gif Мало ли в каком состоянии стеки находятся в том месте, откуда сигануло в прерывание? Вы, положим по метке перейдете, а стек кто чистить будет?

Xenia такой сценарий sm.gif Если уж выполненно определенное условие , то стек и состояние др.регистров неважно

Цитата(ARV @ May 19 2013, 09:49) *
с моей точки зрения ситуация, когда "регистры и состояние стека уже не важны" должна приводить к аппаратному сбросу контроллера, и никак иначе, тем более из прерывания.
Точно! программа должна выполнить определенные действия и завершиться.

Сообщение отредактировал MaxiMuz - May 19 2013, 16:27
Go to the top of the page
 
+Quote Post
_Артём_
сообщение May 19 2013, 20:02
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(MaxiMuz @ May 19 2013, 19:27) *
Точно! программа должна выполнить определенные действия и завершиться.

Если нужно завершить программу, то почему бы не сделать возврат из прерывания не в точку вызова, а туда где лежит фнкция завершающая программу?
Код
volatile unsigned char fatal_error;
void my_exit()
{
    cli();
    while (fatal_error) {
        PORTC^=1;
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
    }
    
}
ISR(SPM_RDY_vect)
{
    SPMCR&=~(1<<SPMIE);
    unsigned char error_detected=0;
    // какие-то дайствия
    //
    if (error_detected) {
        unsigned short sp = SP;
        unsigned short return_address=(unsigned short)my_exit;
        unsigned char *ptr=(unsigned char *)sp;
        fatal_error=1;
        ptr++;
        *ptr++=return_address>>8;
        *ptr++=return_address&255;
        asm("ret");
    }
}
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение May 20 2013, 12:40
Сообщение #9


Местный
***

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



Цитата(_Артём_ @ May 19 2013, 23:02) *
Если нужно завершить программу, то почему бы не сделать возврат из прерывания не в точку вызова, а туда где лежит фнкция завершающая программу?

Вообщето я так и хочу сделать, только не в функцию , а в участок main
Go to the top of the page
 
+Quote Post
_Артём_
сообщение May 20 2013, 13:31
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(MaxiMuz @ May 20 2013, 15:40) *
только не в функцию , а в участок main

Мне почему-то кажется что код идущий после метки будет выкинут оптимизатором. Или нет?
Вы с какими настройками компилируете?
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение May 21 2013, 20:17
Сообщение #11


Местный
***

Группа: Участник
Сообщений: 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 что задействует еще пару регистров, которые сохраняются в стек
Только неясно почему опять кривой костыль ?
Go to the top of the page
 
+Quote Post
_Артём_
сообщение May 21 2013, 20:54
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 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);
}

На запуск програмного прерывания нужно всего пара команд, поэтому дополнительных регистров не потребуется. Только сработает оно через десятков-другой тактов, но программа при этом порушена не будет.
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение May 21 2013, 21:01
Сообщение #13


Местный
***

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



Цитата(_Артём_ @ May 21 2013, 23:54) *
О каких портах речь? Входы-выходы? После сброа они будут сброшены в дефолтное состояние.

тот вариант о котором говорила Xenia
#17
с вызовом прерывани из прерывания я тоже думал , как вариант , но всеже rjmp проще всего
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- 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


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

 


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


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