|
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 проще всего
|
|
|
|
|
May 22 2013, 07:05
|

неотягощённый злом
     
Группа: Свой
Сообщений: 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 частенько используют...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
Сообщений в этой теме
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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|