Теперь о том, почему я так загонялся на тему сбоев при прошивке.
Дело в том что в памяти атмеги есть ячейки отвечающие за параметры конфигурации всего МК — фьюз-биты.
Про фюз-биты, как обычно, можно почитать у ДиХальта.
От себя добавлю что фьюз биты МК Atmega8 расположены в два байта – старший фьюз-байт (high _fuses) и младший фьюз-байт ( low_fuses)
А у Atmega168 есть ещё и дополнительный фьюз-байт(extended_fuses)
Если при программировании МК произойдёт сбой, то с некоторой долей вероятности (у меня пару раз было =) в эти ячейки может залезть мусор, что приведёт к галюцинированию или неработоспособности.
Шьются они специальными командами по 3 байта каждая+1байт данных (“куда писать”+”что писать”) т.е. вероятность, что помеха совпадёт именно с одной из них невелика, однако при прошивке ненадёжным программатором (или в условиях сильных помех) непосредственно фьюз-битов, вероятность попадания в них хлама существенно возрастает (мы сами подаём команду на запись фьюзов и если она каким-то чудом прорвалась сквозь наводки то данные похерить проще (они могут быть произвольными) и МК с радостью схавает шум эфира)
Наиболее неприятные фьюзы:
Ячейка RSTDISBL
при записи в неё “0” превращает вывод резет в обычную ногу и
прошить МК по SPI будет уже невозможно (вначале программирования необходимо “прижать к земле” RESET – подать “0”)
Ячейка SPIEN
при записи в неё “1” запрещено программирование по SPI. Пишут что при
программировании по последовательному каналу данная ячейка недоступна, так что нам вроде не грозит, однако проверять нехочется=)
Ячейки CKOPT и CKSEL
отвечают за тактирование МК и могут встать в такую позу, что
контроллер будет ждать внешнего тактового сигнала или не сможет раскачать ваш кварц.
Первое и второе лечится только параллельным программатром (может и JTAG поможет)
Второе лечится “тактированием от пальца” (мне пару раз помогло=). Тыкаете в XTAL1 (у атмеги8 — 9 нога) иголкой (или отвёрткой неизолированной) и шьёте как обычно — через SPI (может не с первого раза получится =) – можно, конечно использовать внешний генератор, но это если он есть или его не лень сделать =)
Сбои при программировании остальных фьюзов, лок-битов (биты отвечающие за защиту прошивки) и самого бутлоадера могут доставить неприятности лечимые простой (через SPI) перепрошивкой.
Процесс прошивки бутлодера состоит из четырёх этапов:
Разблокирование секции загрузчика вообще-то, по умолчанию, вся память атмеги и так
доступна для чтения/записи.
Установка фюз-битов — настраивает МК на работу в ардуине.
Прошивка собственно бутлодера
Запись лок-битов, защищающих секцию загрузчика от самостоятельной перезаписи (в общем случае бутлоадер может модифицировать или вообще сносить сам себя)
Настройки процесса прошивки бутлодера и значеня фьюз- и лок-битов можно просмотреть в arduino-0015\hardware\boards.txt в соотвествующей нашему МК секции (atmega8.bootloader)
atmega8.bootloader.programmer (по умолчанию: stk500) протокол используемый бутлодером.
atmega8.bootloader.path(по умолчанию: atmega8 ) путь где файл бутлодера лежит
atmega8.bootloader.file(по умолчанию: ATmegaBOOT.hex) собственно, сам бутлоадер
Теперь самое интересное:
atmega8.bootloader.unlock_bits (по умолчанию: 0x3F) значение записываемое в лок-байт для разблокирования секции бутлодера. Сбрасывает все лок-биты в 1 т.е. разрешаем любые изменения секции прикладной программы и бутлаодера.
atmega8.bootloader.high_fuses (по умолчанию: 0xCA) значение записываемое в старший фьюз-байт.
atmega8.bootloader.low_fuses (по умолчанию: 0xDF) значение записываемое в младший фьюз-байт
atmega8.bootloader.lock_bits (по умолчанию:0x0F) значение записываемое в лок-байт для блокирования секции бутлодера — запрещается запись/чтение секци бутлоадера (программатором конечно можно, но ни агрессивный скетч ни суицидально настроенный бутлоадер не смогут=)
Рассмотрим что же именно пишется во фьюз-биты МК:
Atmega8
Младший фьюз-байт
BODLEVEL 1 порог срабатывания схемы BOD 2.7В BODEN 1 но BOD у нас запрещён=) SUT1 0 эта пара определяет длительность задержки сигнала RESET после включения SUT0 1 питания - 16тыс тактов (при 16МГц кварце это 1с) CKSEL3 1 эти фьюзы CKSEL2 1 определяют тип CKSEL1 1 тактирования CKSEL0 1 – кварцевый резонатор >1МГц
Старший фьюз-байт
RSTDISBL 1 ножка RESET – резет WDTON 1 таймер вочдог – запускается программно SPIEN 0 шить через ISP можно CKOPT 0 совместно с CKSEL3...0 определяет что усилитель тактового сигнала включен EESAVE 1 команда “стереть кристалл” стирает также EEPROM BOOTSZ1 0 размер секции BOOTSZ0 1 загрузчика 512байт BOOTRST 0 вектор начального сброса находится в начале секции загрузчика - МК при включении питания первым делом запустит бутлоадер
Atmega168
Старший фьюз-байт
RSTDISBL 1 ножка RESET – резет DWEN 1 работа отладчного интерфейса DebugWire запрещена SPIEN 0 шить через ISP можно WDTON 1 таймер вочдог – запускается программно EESAVE 1 команда “стереть кристалл” стирает также EEPROM BODLEVEL2 1 порог срабатывания BODLEVEL1 0 схемы BOD BODLEVEL0 1 = 2,7В
Младший фьюз-байт
CKDIV8 1 делитель тактового сигнала выключен CKOUT 1 Выходной буфер системного тактового сигнала отключен от вывода МК SUT1 1 эта пара определяет длительность задержки сигнала RESET после вкл.питания SUT0 1 - 16тыс тактов+14тактов +65мс (при 16МГц кварце это немного больше 1с) CKSEL3 1 эти фьюзы CKSEL2 1 определяют тип CKSEL1 1 тактирования CKSEL0 1 - кварцевый резонатор >8МГц
Дополнительный фьюз-байт
- - - - - BOOTSZ1 0 1024байта размер BOOTSZ0 0 секции бутлоадера BOOTRST 0 вектор начального сброса находится в начале секции загрузчика - МК при включении питания первым делом запустит бутлоадер
Ссылки
AVR. Учебный Курс. Конфигурация FUSE бит
AVR Fuse Calculator
По теме
Arduino/CraftDuino и WinAVR — программируем на чистом С
Делаем ISP-программатор из Arduino
0 комментариев на «“Про фьюзы”»
а можно узнать фьюзы для atmega 328
немного не понял про фьюзы: BOOTSZ1,BOOTSZ0,BOOTRST
они хранят адрес загрузчика или что?
BOOTRST — работать с загрузчика (а не с начала памяти, где хранится пользовательская программа)
BOOTSZ1 и BOOTSZ0 — определяют размер секции загрузчика, а так как он находится в «конце» памяти то и соответственно адрес его ими определён, ЕМНИП=)