|
|
  |
Как программно сгенерить ресет? |
|
|
|
May 26 2008, 18:22
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(_Pasha @ May 26 2008, 19:49)  Не верю  Что верю-не верю? Зависит о того, как реализовали startup. Я никогда call main не делаю, бо совсем незачем. А оно это надо приключения на свою голову искать причем абсолютно без какой-бы то ни было надобности??? Цитата(singlskv @ May 26 2008, 20:06)  // останавливаем всю переферию SysTimerStop(); AdcStop(); SpiStop(); PwmStop(); PortsReset(); I2cStop(); Ну и зачем весь этот лишний код? Зачем помнить, что после модификации-добавления надо еще добавить stop()? Watcdog-и есть везде, зачастую есть возможность спровоцировать Watcdog досрочно.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
May 26 2008, 18:36
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(zltigo @ May 26 2008, 22:22)  Ну и зачем весь этот лишний код? Зачем помнить, что после модификации-добавления надо еще добавить stop()? Watcdog-и есть везде, зачастую есть возможность спровоцировать Watcdog досрочно. Я же и не говорю что так нужно делать всегда, конечно вариант с вотчдогом намного надежнее(думать меньше надо  ), ну а если еще и доступ к нему через magic numbers то вобще очень не плохо, не нужно долго ждать, но иногда нужно сделать рестарт очень быстро, и тогда выключение всей переферии за несколько мкс это выход. Ну и тема вроде как называется "Как программно сгенерить ресет?", так что обсуждаем все варианты...
|
|
|
|
|
May 26 2008, 18:51
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Rock @ May 26 2008, 22:13)  Код 8: ((void(*)(void))0)(); +0000003E: DFEF RCALL PC-0x0010 Relative call subroutine 9: for(;;); +0000003F: CFFF RJMP PC-0x0000 Relative jump +00000040: FFFF ??? Data or unknown opcode +00000041: FFFF ??? Data or unknown opcode avr-gcc 4.4 Выдает правильный код проверял для 128 и 8 меги: Код ((void(*)(void))0)(); 76: e0 e0 ldi r30, 0x00; 0 78: f0 e0 ldi r31, 0x00; 0 7a: 09 95 icall Анатолий.
Сообщение отредактировал aesok - May 26 2008, 18:59
|
|
|
|
|
May 26 2008, 19:14
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(_Pasha @ May 26 2008, 21:02)  2singlskv: А скажите пожалуйста, __bad_interrupt всегда был jmp 0 ? Нет, __bad_interrupt заменяеться на jmp 0 для "толстых" чипов и на rjmp __vectors для "тонких", НО, Вы можете переопределить обработчик для незадействованных прерывание(типа контроль), например так: Код ISR(__vector_default) { // вигхня какаята } Ну и джамп в __bad_interrupt будет на Ваш обработчик. to aesok, а почему бы вам не прописать __vectors в хидерах ? Правда наверное тогда завалят вопросами "а почему у меня не работает ...."
|
|
|
|
|
May 26 2008, 19:16
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 18-02-06
Пользователь №: 14 478

|
Цитата(aesok @ May 26 2008, 22:51)  avr-gcc 4.4 Выдает правильный код проверял для 128 и 8 меги: Код ((void(*)(void))0)(); 76: e0 e0 ldi r30, 0x00; 0 78: f0 e0 ldi r31, 0x00; 0 7a: 09 95 icall Анатолий. уточните какая эта версия 2007хххх пожалуйста, придётся обновить ....
|
|
|
|
|
May 26 2008, 19:27
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Rock @ May 26 2008, 23:16)  уточните какая эта версия 2007хххх пожалуйста, придётся обновить ....  я думаю что то типа 2009хххх надо будет у Эрика уточнить. Последняя вышедшая версия WinAVR - 20080512 в ней avr-gcc 4.3. Я уверен что переход на нулевой адрес в ней работает. Если нет пишите. Анатолий. Цитата(singlskv @ May 26 2008, 23:14)  to aesok, а почему бы вам не прописать __vectors в хидерах ? Правда наверное тогда завалят вопросами "а почему у меня не работает ...."  Потому что нет никаких причин переходить на 0 адрес. Переход на нелевой адрес это не ресет. (точка.) avr-libc-user-manual FAQ #30 How do I perform a software reset of the AVR? http://www.nongnu.org/avr-libc/user-manual...l#faq_softresetАнатолий.
Сообщение отредактировал aesok - May 26 2008, 19:35
|
|
|
|
|
May 26 2008, 20:26
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(aesok @ May 26 2008, 23:27)  Потому что нет никаких причин переходить на 0 адрес. Переход на нелевой адрес это не ресет. (точка.) ну давайте все-таки обойдемся без нравоучений, я сам в своем софте лучше знаю когда нужно делать ресет через watchdog а когда рестарт через джамп на 0 адрес... Особенно учитывая что в приведенном Вами линке: Цитата avr-libc-user-manual FAQ #30 How do I perform a software reset of the AVR? http://www.nongnu.org/avr-libc/user-manual...l#faq_softresetЕсть небольшое такое предупреждение  : CAUTION! Older AVRs will have the watchdog timer disabled on a reset. For these older AVRs, doing a soft reset by enabling the watchdog is easy, as the watchdog will then be disabled after the reset. On newer AVRs, once the watchdog is enabled, then it stays enabled, even after a reset! For these newer AVRs a function needs to be added to the .init3 section (i.e. during the startup code, before main()) to disable the watchdog early enough so it does not continually reset the AVR.А по поводу нужности, ну покажите что ли код с использованием watchdog который будет начинать работу заново менее чем через 1мс ... а то что есть по приведенной Вами ссылке, не более чем предупреждение для тех кто не в состоянии провести правильно инициализацию/деинициализацию, ну и уж истиной в последней инстанции это точно не являеться... (типа просто совета так не делать)
|
|
|
|
|
May 26 2008, 21:03
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(singlskv @ May 27 2008, 00:26)  ну давайте все-таки обойдемся без нравоучений, я сам в своем софте лучше знаю когда нужно делать ресет через watchdog а когда рестарт через джамп на 0 адрес... Вы правы, переход на нулевой адрес являеться рестартом программы а не ресетом контроллера. Ресет и рестарт разные вещи и не нужно их путать (я не про Вас). Просто выполнять ресет более надежно. Цитата А по поводу нужности, ну покажите что ли код с использованием watchdog который будет начинать работу заново менее чем через 1мс ... Ну не все вещи в этой жизни можно решить нажимая на кнопочки, в смысле програмно. Програмно AVR-ку можно сбросит за 16мс. Надо быстрее ставте аппаратный формирователь сброса и дергайте его пином. C'EST LA VIE. Цитата а то что есть по приведенной Вами ссылке, не более чем предупреждение для тех кто не в состоянии провести правильно инициализацию/деинициализацию, ну и уж истиной в последней инстанции это точно не являеться... (типа просто совета так не делать) А зачем полагаться на программиста который может ошибиться, может проще подождать 16 мс и быть уверенным что работа программы всегда будет начинаться на контроллере который находиться в предсказуемом состоянии? Я выбираю надежность перед крутизной. Давайте будем считать, что отсутсвие пределения "__vectors" в avr-libc и являеться советом. Анатолий.
Сообщение отредактировал aesok - May 26 2008, 21:07
|
|
|
|
|
May 26 2008, 21:16
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(aesok @ May 27 2008, 01:03)  Давайте будем считать, что отсутсвие пределения "__vectors" в avr-libc и являеться советом. договорились Просто реально бывают ситуации когда нужно "начать все с начала", при этом програмный контроль всего и вся займет кода(и времени) значительно больше чем просто вариант "все остановили, все перезапустили", а 16мс это иногда так много...
|
|
|
|
|
May 27 2008, 03:45
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(singlskv @ May 26 2008, 23:14)  НО, Вы можете переопределить обработчик для незадействованных прерывание(типа контроль), Нет, я имел ввиду по умолчанию. Цитата(defunct @ May 27 2008, 01:36)  пином Reset дергайте  Тогда надо помнить о таких багах: Цитата 2. Part may hang in reset Some parts may get stuck in a reset state when a reset signal is applied when the internal reset state-machine is in a specific state. The internal reset state-machine is in this state for approximately 10 ns immediately before the part wakes up after a reset, and in a 10 ns window when altering the system clock prescaler...... There are theoretical possibilities of this happening also in run-mode. The following three cases can trigger the device to get stuck in a reset-state: - Two succeeding resets are applied where the second reset occurs in the 10ns window before the device is out of the reset-state caused by the first reset. - A reset is applied in a 10 ns window while the system clock prescaler value is updated by software. .............. Возможные последствия усложнения схемы ресета: девайс отъезжает при наносекундных помехах. Лично меня (в моих приложениях) даже подтягивающий резистор на ресете >1кОм уже в ступор вводит. 300 Ом - не больше - ставлю, когда ISP не надо.
|
|
|
|
|
May 27 2008, 18:57
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
По мотивам этой темы озадачился вопросом кодогенерации в Gcc. Ну вобщем все правильно, вышеприведенная ошибка(с неправильным джампом) есть только в более менее давних версиях Gcc. Сравнивалась кодогенерация в версиях gcc_3.4.6 и gcc_4.1.2 : gcc_3.4.6: Код ;; Unconditional and other jump instructions. ....................... (define_insn "call_insn" ....................... return AS1(%~call,%c0); }" ....................... (define_insn "call_value_insn" ....................... return AS1(%~call,%c1); }" gcc_4.1.2: Код ;; Unconditional and other jump instructions. ....................... (define_insn "call_insn" ....................... else if (which_alternative==2) return AS1(%~call,%c0); return (AS2 (ldi,r30,lo8(%0)) CR_TAB AS2 (ldi,r31,hi8(%0)) CR_TAB \"icall\"); }" ....................... (define_insn "call_value_insn" ....................... else if (which_alternative==2) return AS1(%~call,%c1); return (AS2 (ldi, r30, lo8(%1)) CR_TAB AS2 (ldi, r31, hi8(%1)) CR_TAB \"icall\"); }" то есть как видно из рисунка, при переходе от 3.4.6 к 4.1.2 эта ошибка была подправленна, как это точно соотноситься с версиями WinAvr точно не знаю, но думаю что все что было начиная с 200705xx уже правильное.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|