Перейти к содержанию
    

Размер программы в ATmega324P превысил 15 kB и с некоторых пор попытки запрограммировать fuse WDTON безуспешны: программа не стартует. С незапрограммированным все нормально работает. Скорее всего случается таймаут WDT на полпути к main. C такой ситуацией столкнулся впервые и прошу подсказать как ее грамотно преодолеть в IAR? Как получить доступ к коду инициализации, чтобы одной из первых инструкций вставить обращение к переинициализации WDT?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

как ее грамотно преодолеть в IAR? Как получить доступ к коду инициализации, чтобы одной из первых инструкций вставить обращение к переинициализации WDT?
Вам надо определить в проекте функцию __low_level_init(). Посмотрите в документации ее описание и пример.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насколько я понял, для решения задачи нужно создать проект библиотеки на основе стандартной CLIB, внести туда изменения (в __low_level_init()) и скомпилировать эту "свою" библиотеку. Далее эту свою библиотеку подключить к проекту. Странно, но редактор в проекте библиотеки ругается на // комменты, /* а такие */ воспринимает нормально. Это баг?

И что же теперь, по каждому чиху перекомпилировать стандартные либы? Других способов видимо нет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насколько я понял, для решения задачи нужно создать проект библиотеки на основе стандартной CLIB, внести туда изменения (в __low_level_init()) и скомпилировать эту "свою" библиотеку. Далее эту свою библиотеку подключить к проекту. Странно, но редактор в проекте библиотеки ругается на // комменты, /* а такие */ воспринимает нормально. Это баг?

И что же теперь, по каждому чиху перекомпилировать стандартные либы? Других способов видимо нет?

Поняли неправильно. В Вашем файле с функцией main определяете функцию __low_level_init() в которой отключаете сторожевой таймер на время инициализации. Далее настраиваете свое приложение и включаете сторожевой таймер.

Конкретно с IAR для AVR не работал, но идеология у IAR общая. Для MSP430 делаю именно так.

Если функция не определена, то ничего не делается. Если определена, то вызывается до main. Обратите внимание на возвращаемое значение 1 или 0, в зависимости от которого идет инициализация сегментов памяти.

Лучше всего почитать документацию на компилятор для деталей.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насколько я понял, для решения задачи нужно создать проект библиотеки на основе стандартной CLIB, внести туда изменения (в __low_level_init()) и скомпилировать эту "свою" библиотеку.
Где вы нашли такое в документации?? Просто добавьте в свой проект функцию
int __low_level_init()
{
    // тут все, что вы хотите выполнить сразу же после инициализации указателя стека

    return 1;
}

Если проект на С++, то функцию надо объявить с extern "C"

 

Странно, но редактор в проекте библиотеки ругается на // комменты, /* а такие */ воспринимает нормально. Это баг?
Редактор ругается или все же компилятор? Посмотрите в настройках проекта раздел C/C++ compiler -> Language. Там надо выбрать Allow IAR extensions.

Дело в том, что коментарии '//' - это из С++, в стандартном С89 таких комментариев нет.

 

И что же теперь, по каждому чиху перекомпилировать стандартные либы?
Достаточно просто вдумчиво читать документацию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Большое спасибо, это совсем другое дело! Правда и с перекомпилированными библиотеками получилось, но слишком громоздкий извращенный способ для такой простой цели... :cheers:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Инициализационные код в IAR-вских библиотеках достаточно быстрый. Врядли он тянет на срабатывание WD. Скорее всего вы на С++ наделали классов определённых глобально и это их конструкторы работают. В них тоже wdr натыкать надо. Ну и, как уже писали, в __low_level_init() задать корректные значения для WD. Мне кажется, что программа, ловящая WDR уже на инициализации, с такими параметрами WD будет ловить его и в ходе работы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зачем было включать WDTON на фузах? Задача решается гораздо проще, если этот фуз не включать, а watch dog включить программно в cамом начале main(). Тогда, каким бы ни был продолжительным по времени setup(), watch dog работает нормально. А на сетапе прога не застрянет - он умными людьми писан :).

P.S. Пока я не прочла эту тему, то думала, что все делают так, как я.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А на сетапе прога не застрянет - он умными людьми писан :)
Количество ума не влияет на это никак. Если произошёл сбой хода выполнения программы из-за сбоя аппаратных средств (а память и регистры тоже являются таковыми), то при отключенном WDT можно и на startup загнуться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Скорее всего вы на С++ наделали
Нет, писано на С. Проблема вылезла именно с увеличением объема кода. Времени не хватало, пришлось писать быстро, возможно в ущерб качеству, но др выхода не было. По-моему, там пришлось даже компилятору инициализировать несколько переменных в EEPROM. А это время... Вот WDT и успел сработать. По памяти в ATmega324P по сбросу WDT устанавливается на 16ms (мин значение). ИМХО, вполне реально преодолеть...

 

WDTON я просто поставил для проверки, когда проблема обнаружилась, и начал уменьшать код. В определенный момент при меньшем объеме все заработало... А так, конечно, этот фуз у меня не запрограммирован, а WDT включаю программно, когда нужно...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если произошёл сбой хода выполнения программы из-за сбоя аппаратных средств (а память и регистры тоже являются таковыми), то при отключенном WDT можно и на startup загнуться.

 

Перед смертью не надышишься - если у вас память и регистры сбоят, то watch dog вам не поможет. Даже лучше будет, если такой дерьмовый проц не запустится, чем если он начнет что-то делать с такими регистрами и памятью. Дурью, господа, маетесь. стараясь запустить проц, который не может пройти setup без ошибок.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дурью, господа, маетесь. стараясь запустить проц, который не может пройти setup без ошибок.
Давайте не будем столь категорично оценивать друг друга. Ведь зачем-то этот фуз вставили в процессор? Значит есть такие задачи, где WDT должен быть включен при исполнении стартапа.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ведь зачем-то этот фуз вставили в процессор? Значит есть такие задачи, где WDT должен быть включен при исполнении стартапа.

Очень возможно, что такие задачи существуют. Но в данной теме обсуждается проблема раннего срабатывания watch dog'а. Т.е. синдром как раз таков, который происходит от неудачно установленной фузы. Отсюда и ответ - не ставить эту фузу, раз уж такая проблема возникла. А не решать проблему через ухо - мы де setup перепишем и туда через строчку __watchdog_reset() понавтыкаем.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очень возможно, что такие задачи существуют. Но в данной теме обсуждается проблема раннего срабатывания watch dog'а.
Подобным методом можно отсечь любые аргументы. В исходном посте не было описано "такая" задача у автора или нет. Раз он включил собаку - значит мы должны предположить, что сделал он это сознательно и что задача именно "такая". Бороться надо не со следствием, а с причиной. Если на стартап нужно больше времени - значит надо правильно настроить собаку перед выполнением стартапа (и, возможно, снова перенастроить после стартапа), а не отключать ее. И именно такое решение и просил автор.

Ваш метод решения напоминает установку гвоздя вместо "автомата" на лестнице, который постоянно выбивало из-за стиралки, бойлера и "теплых" полов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Значит есть такие задачи, где WDT должен быть включен при исполнении стартапа.

Возможно. Назовешь, хоть одну? Типа отлаживались без WD медленно и печально а потом fuse включили (главное не забыть) и отдали в серию? Но тут startup ни причем.... У меня до сих пор фантазии как-то не хватило и включаю WD ручками, если включаю. Если вдруг должен будет включен во время startup, то там не только проинициализирую, но и включу. Позицию разработчиков некоторых контроллеров, которые по reset всегда WD включают и дают потом возможность один раз отключить или перенастроить я еще понимаю, но зачем разновариантность вводить-то?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...