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

 
 
> возврат к началу программы из прерывания
1100.1010.1011.1...
сообщение Apr 6 2011, 21:44
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 22-10-10
Пользователь №: 60 334



Написана простенькая програмка работы с портами ввода/вывода(WinAvr).(последовательно и в определенном порядке включает релюшки). Предусмотрено внешнее прерывание (аварийно отключает релюшки). После наступления прерывания (аварии) необходимо заново проделывать всю программу сначала.Как это сделать?Не дергать же портом ножку ресет?))
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 14)
V_G
сообщение Apr 6 2011, 22:02
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Смотря какой процессор и какая у вас конфигурация.
Если xmega, там есть программный ресет.
Если используется вочдог, можно вызвать ресет бесконечным циклом.
Если не то и не другое, запретить прерывания, настроить стек (если он в начале программы не настраивается), сбросить все настройки периферии (особенно разрешения прерываний), которые могут помешать вашей программе (если авария, может, и периферия расстроена?), и уйти на вектор ресета (0 или бутлоадер)

Сообщение отредактировал V_G - Apr 6 2011, 22:03
Go to the top of the page
 
+Quote Post
1100.1010.1011.1...
сообщение Apr 7 2011, 05:18
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 22-10-10
Пользователь №: 60 334



ATtiny25.С вочдогом интересная идея,нужно будет попробовать. Примерный код обработчика прерывания
ISR(INT0_vect)
{
SetBit(PORTB,RBT);
_delay_ms(100);
ClearBit(PORTB,RBT);
ClearBit(PORTB,K1);
//здесь сделать ресет
}
Подскажите как уйти на 0x0000 средствами WinAvr?
Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 7 2011, 07:35
Сообщение #4


Гуру
******

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



Цитата(1100.1010.1011.1010 @ Apr 7 2011, 09:18) *
Подскажите как уйти на 0x0000 средствами WinAvr?
Так же, как и на любом другом трансляторе
Код
void (* Reset)(void)= (void *)0;
........
Reset();

Go to the top of the page
 
+Quote Post
1100.1010.1011.1...
сообщение Apr 7 2011, 10:13
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 22-10-10
Пользователь №: 60 334



чудеса,работает!спасбо!Не могли бы вы пояснить код?как он работает?
Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 7 2011, 10:51
Сообщение #6


Гуру
******

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



Цитата(1100.1010.1011.1010 @ Apr 7 2011, 14:13) *
Не могли бы вы пояснить код?
Ну, собственно, тут-то всего две строчки: 1) определяем указатель на функцию со значением ноль 2) вызываем функцию по указателю, т.е. переходим на выполнение функции, код которой якобы расположен с адреса ноль.


Хочу обратить внимание, что с помощью WDT - "честный" сброс МК, а код, приведенный мною - всего лишь "перезапуск" программы. Т.е. устройства, которые в этот момент работали - будут продолжать работать (например, USART - выдавать/принимать данные), что не всегда допустимо!
Go to the top of the page
 
+Quote Post
1100.1010.1011.1...
сообщение Apr 7 2011, 11:08
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 22-10-10
Пользователь №: 60 334



C WDT понятно.Не совсем понял (и не нашел в нете) синтаксис функции.
void (*function)(void) * это знак нулевой функции?
и что означает (void *)0;

и где бы почитать про такие фенкции?

Сообщение отредактировал 1100.1010.1011.1010 - Apr 7 2011, 11:15
Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 7 2011, 11:35
Сообщение #8


Гуру
******

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



Цитата(1100.1010.1011.1010 @ Apr 7 2011, 15:08) *
Не совсем понял (и не нашел в нете) синтаксис функции.
Это - указатель на функцию - т.е. ячейка памяти, которая содержит адрес начала функции. Этому указателю присваиваем нулевое значение (вернее - указатель на нулевой адрес). При обращении к функции по указателю МК перейдет на команду с адресом равным значению указателя функции - в данном случае: указан адрес 0 как адрес начала функции.
Go to the top of the page
 
+Quote Post
SysRq
сообщение Apr 7 2011, 14:08
Сообщение #9


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Код
#include <avr/wdt.h>
#include <avr/interrupt.h>

__attribute__((noreturn)) void restart(void)
{
    cli();
    
    wdt_reset();
    wdt_enable(WDTO_15MS);
    
    for(;;); // Die, die my darling!
}
Go to the top of the page
 
+Quote Post
1100.1010.1011.1...
сообщение Apr 8 2011, 15:54
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 22-10-10
Пользователь №: 60 334



Тоже прошу немного пояснить ... blush.gif
Go to the top of the page
 
+Quote Post
Xenia
сообщение Apr 8 2011, 15:59
Сообщение #11


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



SysRq, скажите, а зачем нужен wdt_reset() после cli?
Если расчет берется на то, что прежний установленный интервал был велик, то тогда wdt_reset() имел бы смысл только после wdt_enable(WDTO_15MS), и то сомнительно. А так я не вижу от него никакого толка.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 8 2011, 16:24
Сообщение #12


Гуру
******

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



Цитата(1100.1010.1011.1010 @ Apr 8 2011, 19:54) *
Тоже прошу немного пояснить ...
Ну, Вы, блин, даёте... Запретить прерывания; настроить WDT; уйти в бесконечный цикл; поскольку WDT сбрасывать никто не собирается, то через некоторое время WDT перезапустит МК...
Go to the top of the page
 
+Quote Post
1100.1010.1011.1...
сообщение Apr 8 2011, 16:29
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 22-10-10
Пользователь №: 60 334



Палыч,то что вы пояснили как раз понятно.Не все ясно с __attribute__((noreturn)) void restart(void)
Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 8 2011, 16:45
Сообщение #14


Гуру
******

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



Цитата(Xenia @ Apr 8 2011, 19:59) *
скажите, а зачем нужен wdt_reset() после cli?
В данном случае - не нужен. Просто кусочек программы взят из DS из примера "нормального" запуска WDT


Цитата(1100.1010.1011.1010 @ Apr 8 2011, 20:29) *
Палыч,то что вы пояснили как раз понятно.Не все ясно с __attribute__((noreturn)) void restart(void)
Из функции нет возврата управления
Go to the top of the page
 
+Quote Post
SysRq
сообщение Apr 8 2011, 17:29
Сообщение #15


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(Xenia @ Apr 8 2011, 19:59) *
SysRq, скажите, а зачем нужен wdt_reset() после cli?
Вы правы, пожалуй. Не нужен он. Уберём-с sm.gif

--

Цитата(1100.1010.1011.1010 @ Apr 8 2011, 20:29) *
Не все ясно с __attribute__((noreturn)) void restart(void)
Функция с таким атрибутом имеет пролог поменьше, стека расходует меньше, т.к. не сохраняет call-saved регситры -> выполняется быстрее, и проще учитывать необходимый размер стека.
Go to the top of the page
 
+Quote Post

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

 


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


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