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

 
 
> 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
demiurg_spb
сообщение May 22 2013, 06:52
Сообщение #14


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Всё это (аварийный выход) стоит завернуть в какой-нибудь макрос с внятным именем типа abort();
Кстати, вариант с программным прерыванием - ИМХО самый оптимальный - вызов одна инструкция sbi, ну и обработчик со всеми нужными атрибутами...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Палыч
сообщение May 22 2013, 07:01
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(demiurg_spb @ May 22 2013, 10:52) *
вызов одна инструкция sbi...

В AVR программное прерывание "сгенерить" не так-то и просто. В АVR, обычно, запись единицы в флаг прерывания приводит к её сбросу.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение May 22 2013, 07:05
Сообщение #16


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Палыч @ May 22 2013, 11:01) *
В AVR программное прерывание "сгенерить" не так-то и просто. В АVR, обычно, запись единицы в флаг прерывания приводит к её сбросу.
На худой конец можно задействовать и внешнее прерывание + дёрнуть уровень на ноге sbi или cbi или просто его разрешить на нужной ноге с нужным уровнем.
Всё это уже лирика...
Цитата
• Bit 7 – SPMIE: SPM Interrupt Enable
When the SPMIE bit is written to one, and the I-bit in the Status Register is set (one), the SPM
ready interrupt will be enabled. The SPM ready Interrupt will be executed as long as the SPMEN
bit in the SPMCR Register is cleared.
Ведь не зря же его для нужд rtos частенько используют...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
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
|||- - 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 Текстовая версия Сейчас: 23rd July 2025 - 08:04
Рейтинг@Mail.ru


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