Прошивка AVR через бутлоадер.
Так как USB программатор у меня появился не сразу, а шить через com порт было медленно и неудобно, пришлось искать выход из сложившейся ситуации и заключался он в использовании бутлоадера. Бутлоадер - это программа, которая получает прошивку по выбранному интерфейсу, например uart, и зашивает её в микроконтроллер.
В одной из прошлых статей описывалось как прошить STM32 с помощью бутлоадера, но у STM32 бутлоадер зашивают в чип ещё при его изготовлении на заводе, нам же предстоит зашить его самим. Вот как это выглядит в общих чертах, мы берём тот самый бутлоадер и зашиваем его в микроконтроллер, всё, больше программатор нам не понадобится, затем с помощью специальной программы, по uart или RS485, конектимся с бутлоадером и передаём ему прошивку, которую хотим зашить в МК, дальше он всё сделает сам.
Сначала надо выбрать бутлоадер, для AVR подойдёт chip45boot2, ниже список поддерживаемых им контроллеров на текущий момент.
Качаем hex бутлоадера для нашего микроконтроллера и программу тут.
Теперь когда у нас есть все необходимые инструменты, можно приступать. В папке с бутлоадерами находим hex в котором присутствует название нашего МК, у меня Atmega16, и зашиваем его предварительно выставив фьюзы BOOTSZ и BOORST.
BOOTSZ – определяет размер загрузчика, а BOORST – откуда будет стартовать МК после сброса.
У меня в Atmel Studio фьюзы выглядят так.
Но в других программах, фьюзы могут быть инвертированы, для того чтобы понять так ли это, можно считать текущее значение фьюзов и посмотреть чему равены SPIEN и JTAGEN – биты разрешающие прошивку МК по SPI и JTAG, уж если ты смог подключиться к МК, то наверняка по одному из этих интерфейсов. По умолчанию они установлены и галочки должны стоять, если же напротив фьюза интерфейса, по которому ты подключился, галочка не стоит, фьюзы надо инвертировать.
Теперь после сброса МК будет стартовать с загрузочной секции, там где находится бутлоадер, он в свою очередь будет ждать, что ему передадут прошивку, которую он должен будет зашить в МК. На ожидание выделен определенный промежуток времени, несколько секунд, если в течении этого промежутка времени к нему не обращаются, МК переходит к выполнению основной программы. Давайте подключимся к нему по uart, для этого нам понадобится переходник usb-uart, вывод RX переходника соединяется с выводом TX микроконтроллера, а вывод TX переходника с выводом RX микроконтроллера.
Открываем программу chip45boot2, выбираем com port, под которым определился наш переходник usb-uart, скорость определится сама, сбрасываем МК и нажимаем Connect to Bootloader. В случае успешного подключения лампочка Status изменится на Connected и станет ярко зелёной.
Теперь выбираем hex и/или eeprom файл и жмём кнопку Program Flash и/или Program Eeprom. Всё, процедура прошивки закончена, если по ошибке прошить МК программатором бутлоадер "слетит" и для его восстановления процедуру придётся повторить.
Попасть в загрузочную секцию можно еще одним способом, из таблицы выше видно, что при размере бутлоадера 1024 слова, загрузочная область начинается с адреса $1C00, начать выполнение программы с этого адресу можно c помощью указателя на функцию.
И то же самое на ассемблере
Теперь не надо сбрасывать МК для соединения с бутлоадером, достаточно просто отправить ему букву b.
В одной из прошлых статей описывалось как прошить STM32 с помощью бутлоадера, но у STM32 бутлоадер зашивают в чип ещё при его изготовлении на заводе, нам же предстоит зашить его самим. Вот как это выглядит в общих чертах, мы берём тот самый бутлоадер и зашиваем его в микроконтроллер, всё, больше программатор нам не понадобится, затем с помощью специальной программы, по uart или RS485, конектимся с бутлоадером и передаём ему прошивку, которую хотим зашить в МК, дальше он всё сделает сам.
Сначала надо выбрать бутлоадер, для AVR подойдёт chip45boot2, ниже список поддерживаемых им контроллеров на текущий момент.
Качаем hex бутлоадера для нашего микроконтроллера и программу тут.
Теперь когда у нас есть все необходимые инструменты, можно приступать. В папке с бутлоадерами находим hex в котором присутствует название нашего МК, у меня Atmega16, и зашиваем его предварительно выставив фьюзы BOOTSZ и BOORST.
BOOTSZ – определяет размер загрузчика, а BOORST – откуда будет стартовать МК после сброса.
У меня в Atmel Studio фьюзы выглядят так.
Но в других программах, фьюзы могут быть инвертированы, для того чтобы понять так ли это, можно считать текущее значение фьюзов и посмотреть чему равены SPIEN и JTAGEN – биты разрешающие прошивку МК по SPI и JTAG, уж если ты смог подключиться к МК, то наверняка по одному из этих интерфейсов. По умолчанию они установлены и галочки должны стоять, если же напротив фьюза интерфейса, по которому ты подключился, галочка не стоит, фьюзы надо инвертировать.
Теперь после сброса МК будет стартовать с загрузочной секции, там где находится бутлоадер, он в свою очередь будет ждать, что ему передадут прошивку, которую он должен будет зашить в МК. На ожидание выделен определенный промежуток времени, несколько секунд, если в течении этого промежутка времени к нему не обращаются, МК переходит к выполнению основной программы. Давайте подключимся к нему по uart, для этого нам понадобится переходник usb-uart, вывод RX переходника соединяется с выводом TX микроконтроллера, а вывод TX переходника с выводом RX микроконтроллера.
Открываем программу chip45boot2, выбираем com port, под которым определился наш переходник usb-uart, скорость определится сама, сбрасываем МК и нажимаем Connect to Bootloader. В случае успешного подключения лампочка Status изменится на Connected и станет ярко зелёной.
Теперь выбираем hex и/или eeprom файл и жмём кнопку Program Flash и/или Program Eeprom. Всё, процедура прошивки закончена, если по ошибке прошить МК программатором бутлоадер "слетит" и для его восстановления процедуру придётся повторить.
Попасть в загрузочную секцию можно еще одним способом, из таблицы выше видно, что при размере бутлоадера 1024 слова, загрузочная область начинается с адреса $1C00, начать выполнение программы с этого адресу можно c помощью указателя на функцию.
#define F_CPU 8000000UL
#define Boot_Address 0x1C00
#include <avr/io.h>
#include <avr/interrupt.h>
void (*Goto_Boot)(void);
ISR(USART_RXC_vect)
{
if (UDR == 'b')
{
Goto_Boot = (void(*)())Boot_Address;
Goto_Boot();
}
}
int main(void)
{
UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(0<<UDRIE);
UCSRC = (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);
UBRRL = 0x33;
sei();
while(1)
{
}
}
И то же самое на ассемблере
.cseg
.org $0
rjmp Reset
.org $016
rjmp RX_Complete
Reset:
ldi R16, low(RAMEND)
out SPL,R16
ldi R16, high(RAMEND)
out SPH,R16
ldi R16,(1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(0<<UDRIE)
out UCSRB,R16
ldi R16,(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)
out UCSRC,R16
ldi R16, $33
out UBRRL,R16 ;настройка скорости 9600
sei
main:
rjmp main
RX_Complete:
in R16, UDR
cpi R16, 'b'
breq Goto_Boot
reti
Goto_Boot:
ldi ZH, $1C
ldi ZL, $00
icall
ret
Теперь не надо сбрасывать МК для соединения с бутлоадером, достаточно просто отправить ему букву b.
Похожие статьи