WATCHDOG

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

Поздравляю всех с наступающим праздником.

Вопрос: как программно зафиксировать количество сработак собаки не используя EEPROM.

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Нужно программно только завиксировать (а считывать будет человек) или программно же потом считывать?

В любом случае, использовать внешние инструменты запоминания. Любые. Вариантов миллион. Сразу же после загрузки у Вас есть возможность узнать была ли она вызвана watchdog или другой причиной. Вот, если watchdog - делайте что-нибудь во внешнем мире, что запомнится независимо от питания и перезагрузок (единичку на принтер выводите :) )

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

Cистема должна работать без участия оператора длительное время, фиксация собаки требуется для статистики (стабильность работы), оператор снимает показания 1 раз в неделю.

 

bwn
Offline
Зарегистрирован: 25.08.2014

oleg_kazakof пишет:

Cистема должна работать без участия оператора длительное время, фиксация собаки требуется для статистики (стабильность работы), оператор снимает показания 1 раз в неделю.

Зависит, что в системе кроме МК есть. Например в RTC есть собственное ОЗУ.

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

Факсировать собаку предпологал только внутренними возможностями ардуино (UNO), возможно есть способ не инициализировать переменную после ресета ?, использование EEPROM крайний вариант.

 

bwn
Offline
Зарегистрирован: 25.08.2014

Предположим, 100 раз сработала собака, на 101 отключили питание - сколько раз сработала собака, с точки зрения оператора?

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

используется буферный источник питания.

 

bwn
Offline
Зарегистрирован: 25.08.2014

Возможно здесь и не прав, не лазал глубоко. Но вроде основная задача собаки как раз пнуть МК и привести его в работоспособное состояние, начав все с чистого листа.

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

Да всё верно, основная задача собаки  - полный ресет, вопрос в том как оставить после ресета кусочек листа оставить грязным тоесть присвоить переменной статус неинициализируемой.

  

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну. Вы же знаете при загрузки от чего она произошла, от дога или нет. Ну, и пользуйте это знание.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Где-то уже писали что  при старте можно  выяснить по какой причине был этот старт.

bwn
Offline
Зарегистрирован: 25.08.2014

ЕвгенийП, trembo, ТС насколько понимаю, хочет через неделю узнать, сколько раз был этот старт. При этом не трогать епром МК и не испоьзовать ничего стороннего.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Если без епром.........    можно на стенке зарубки царапать чем-то, как в фильмах.......
пару серв  и карандаш.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Коллеги, не забываем что статусный регистр  MCUSR  с причинами загрузок бутлоадер заботливо отчищает :) Так что юзать эту фичку можно только без бутлоадера.

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015
НАШЁЛ ВОТ ТАКОЙ ПОСТ ОТ ЕвгенийП. Но пока не проверял может кто пробовал подскажите .

Как исполнить свой код ДО инициализации среды Arduino?
ЕвгенийП 
 
Коллеги, тут как-то обсуждался вопрос, как выполнить некий код сразу же после загрузки процессора (до инициализации среды Arduino). Кажется, вопрос был связан с отключение сработавшего WatchDog'а, который, как известно, должен быть отключён очень быстро (сколько-то микросекунд) после загрузки, а среда инициализируется дольше.
Мне тут по другому поводу понадобилось нечто подобное. Сделал и решил показать всем, как это делается.
В приведённом примере функция preInit – это САМЫЕ ПЕРВЫЕ команды процессора, которые выполняются непосредственно после Reset. До них не выполняется ничего – не инициализирован стек, не инициализирован глобальные переменные, не отработали конструкторы глобальных объектов (привет Serial'у – он ещё не «родился») - ничего!
Имейте в виду – у Вас нет ничего, даже нормального стека!
Чисто показать «первость» не могу (просто верю документации), но косвенно, смотрите:
1. переменная cat2 объявлена «как обычно» (и стало быть она будет проинициализирована нулём при общей инициализации среды), а переменная cat1 объявлена с указанием «не инициализировать».
2. В функции preInit я записываю в обе переменные ненулевые значения.
3. При печати видно, что cat1 сохранила своё значение, а cat2 стала нулём.
Вывод: функция preInit выполнялась, по крайней мере, ДО инициализации глобальных переменных.
01 //
02 //  Эксперимент на кошках!
03 //  Проверка функций инициализации (функций исполняемых до всего остального)
04 //
05 //  Глобальная переменная cat1 помечена как "неициализируемая", 
06 //  чтобы предотвратить присваивание ей нуля в секции .init4
07 //  cat2 описана стандартно.
08 //
09 int cat1 __attribute__ ((section (".noinit")));
10 int cat2;
11  
12 //
13 //  Функция preInit будет выполняться ДО ВСЕГО
14 //  прямо в момент "сотворения мира" (секция .init0)
15 //  Однако в этот момент ещё даже не инициализирован стек!
16 //  Стек инициализируется в секции .init2, потому, если возможно, лучше 
17 //  нам использовать не .init0 как здесь, а .init3
18 //  тогда хоть стеком можно пользоваться.
19 //
20 void preInit (void) __attribute__ ((naked)) __attribute__ ((section (".init0")));
21  
22 void preInit (void) {
23     cat1 = 321;
24     cat2 = 123;
25 }
26  
27 void setup() {
28   Serial.begin(115200);
29   Serial.println("Test on cats");
30   Serial.print("Cat #1:");
31   Serial.println(cat1);
32   Serial.print("Cat #2:");
33   Serial.println(cat2);
34 }
35  
36 void loop() {}
  
Sindbad 
Т.е. если записать

1 void preInit (void) {
2     while (true);
3 }
Потребуется перепрошивка загрузчика?

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

А что вы хотите выполнить до инициализации среды ардуино? 

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

В cat1 сохранять количество лаев собаки.

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

oleg_kazakof, имхо для этого не нужно лезть в но_инит_ секцию. Вроде бы этот регистр читается до тех пор, пока его кто нибудь не обнулит. И вроде бы кроме библы wdt в него никто не лезет.  Так что перепишите общение с собакой обычными битовыми операциями, (иначе библа обнулит быстрее чем вы считаете этот регистр) и дело в шляпе.  Но разумеется бутлоадер никак не обогнуть, придёться от него отказаться совсем.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Погуглил из любопытства по теме, оказывается в последних оптибутах что-то слегка пофиксили. Потестил последний оптибут (v 6.2  https://github.com/Optiboot/optiboot) Всё равно всё криво. MCUSR переписывается в  другой регистр , и затирается.  А  прочесть тот регистр можно только через хитрые секции (пример как это сделать есть в архиве test_reset.ino), но на все причины, кроме браун-аута пишет что перегружал вотчдог. Дурь какая-то. Без бутлоадера всё чётко, не нужно никаких выкрутасов с секциями, всё читается и значения  отдаются такие, какие надо. В принципе исходник оптибута есть, можно в нём убрать строки проверки этого регистра, перекомпилить, и сделать бутлоадер без проверки mcusr. Но там вроде как специально задумывали, что бы бутлоадер не грузился всегда, а грузился только после внешнего ресета, поэтому они и анализируют причину загрузки, и регистр отчищают. В общем кому надо, у вас два пути -переписать оптибут как надо или отказаться от него. Второе проще :)

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

Cпасибо всем принявшим участие в теме. Судя  по коментариям самое рациональное решение будет всё же  использование EEPROM.

 C новым годом.