Программатор avrdude и stk500. Ускорение прошивки

8-битные микроконтроллеры AVR (AT90, ATtiny, ATmega) от Atmel (в настоящий момент принадлежит Microchip)

Moderator: Shaos

SfS
Doomed
Posts: 491
Joined: 16 Apr 2005 22:35
Location: Томск

Программатор avrdude и stk500. Ускорение прошивки

Post by SfS »

Давненько я не присал ничего для AVR. И вот, внезапно, возникла тень прошлого - микроконтроллер at90s8535, в который необходимо было залить некое ПО.
Что за ПО - неважно. Важно то, что я пользуюсь самодельным программатором stk500 и программой avrdude.

Запускал прошивку микроконтроллера я такой командой:

Code: Select all

~# avrdude -P /dev/ttyUSB1 -c stk500v2 -p 8535 -U flash:w:main.hex
Тестовая программка, занимающая 240 байт (не килобайт и не мегабайт!) бинарного кода прошивалась у меня за 16 (!!!!) секунд.

Меня это очень огочило. Потому что примерный рассчёт показывал, что 8Кбайт будет с такой скоростью прошиваться около 9 минут. Это нереально долго.

Расследование показало, что если для чипа не указаны парамеры paged, page_size и num_pages, то обмен между ПК и программатором идёт побайтно, а не блоками. То есть на каждый прошиваемый байт передаётся 14 байт запроса и 14 байт ответа. Даже на скорости 115200, с которой работет stk500, это очень медленно.

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

Теперь, как это всё сделать практически.
Считаем, что у вас уже есть линукс и установленный avrdude.
Файл с описаниями программаторов и процессоров лежит тут: /etc/avrdude.conf. Копируем его в свой домашний каталог под именем .avrduderc:

Code: Select all

# cp /etc/avrdude.conf     ~/.avrduderc
Затем заходим в него, находим описание нужного контроллера и указываем там параметры для flash-памяти: paged=yes, page_size=256 и num_pages=size/page_size.
В нашем примере, для at90s8535 num_pages=32.

В сплойере всё описание (пример для at90s8535), исправления выделены жирным шрифтом:

 
#------------------------------------------------------------
# AT90s8535
#------------------------------------------------------------

part
id = "8535";
desc = "AT90S8535";
stk500_devcode = 0x61;
avr910_devcode = 0x68;
signature = 0x1e 0x93 0x03;
chip_erase_delay = 20000;
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
"x x x x x x x x x x x x x x x x";

chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
"x x x x x x x x x x x x x x x x";

timeout = 200;
stabdelay = 100;
cmdexedelay = 25;
synchloops = 32;
bytedelay = 0;
pollindex = 3;
pollvalue = 0x53;
predelay = 1;
postdelay = 1;
pollmethod = 0;

pp_controlstack =
0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
hventerstabdelay = 100;
progmodedelay = 0;
latchcycles = 0;
togglevtg = 0;
poweroffdelay = 0;
resetdelayms = 0;
resetdelayus = 0;
hvleavestabdelay = 15;
chiperasepulsewidth = 15;
chiperasepolltimeout = 0;
programfusepulsewidth = 2;
programfusepolltimeout = 0;
programlockpulsewidth = 0;
programlockpolltimeout = 1;

memory "eeprom"
size = 512;
min_write_delay = 9000;
max_write_delay = 20000;
readback_p1 = 0x00;
readback_p2 = 0xff;
read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
"a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";

write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
"a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";

mode = 0x04;
delay = 12;
blocksize = 128;
readsize = 256;
;
memory "flash"
paged = yes;
page_size = 256;
num_pages = 32;

size = 8192;
min_write_delay = 9000;
max_write_delay = 20000;
readback_p1 = 0xff;
readback_p2 = 0xff;
read_lo = " 0 0 1 0 0 0 0 0",
" x x x x a11 a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";

read_hi = " 0 0 1 0 1 0 0 0",
" x x x x a11 a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";

write_lo = " 0 1 0 0 0 0 0 0",
" x x x x a11 a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" i i i i i i i i";

write_hi = " 0 1 0 0 1 0 0 0",
" x x x x a11 a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" i i i i i i i i";

mode = 0x04;
delay = 12;
blocksize = 128;
readsize = 256;
;
memory "signature"
size = 3;
read = "0 0 1 1 0 0 0 0 x x x x x x x x",
"x x x x x x a1 a0 o o o o o o o o";
;
memory "fuse"
size = 1;
read = "0 1 0 1 1 0 0 0 x x x x x x x x",
"x x x x x x x x x x x x x x x o";
write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i",
"x x x x x x x x x x x x x x x x";
min_write_delay = 9000;
max_write_delay = 9000;
;
memory "lock"
size = 1;
read = "0 1 0 1 1 0 0 0 x x x x x x x x",
"x x x x x x x x o o x x x x x x";
write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
"x x x x x x x x x x x x x x x x";
min_write_delay = 9000;
max_write_delay = 9000;
;
;

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

Ньюансы:
1. page_size нельзя указывать более 256.
2. корректно рассчитывайте num_pages, иначе avrdude ругается и отказывается работать.

Всё решение - на скорую руку, так что если вылезут какие ошибки - я не виноват. :)
User avatar
VituZz
God
Posts: 1343
Joined: 13 Nov 2010 04:06

Re: Программатор avrdude и stk500. Ускорение прошивки

Post by VituZz »

Я использую avreal и STK200, работает быстро без всяких сложностей. Правда, именно в этот контроллер прошивку не вталкивал.
Я использовал STK500 by Petka. Но, как я понял, это проблема не программатора, а программки avrdude. Там сложностей то - две строчки в конфиг добавить. Может кому поможет.