|
Распаковка zip на стороне ATmega, Программирование больших ПЛИС - распаковка прошивок zip |
|
|
|
Nov 3 2010, 14:23
|
Группа: Участник
Сообщений: 9
Регистрация: 15-01-10
Пользователь №: 54 837

|
Здравствуйте,
Прошиваю два Spartan3 с помощью AVR Atmega2561, последовательно, один за другим. Использую WinAVR 2010****. Прошивки для обеих ПЛИС компоную с прошивкой для ATmega. НО прошивки для ПЛИС со временем стали довольно большими и не влезают в 256 Кб для ATmega. Битовое сжатие не помогает.
Придёться сжимать и распаковывать их потом с помощью самого ATmega при программировании ПЛИС. Существуюит ли алгоритмы распаковки zip для ATmega или какие-то другие решения этой проблемы? То, что я находил в сети работет с файлами, а в ATmega файлов по сути никаких и нет.
Буду благодарен за любую предоставленную помощь.
|
|
|
|
|
Nov 3 2010, 15:16
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Да, 10+ лет назад это интенивно обсуждалось в PVT.HARDW.MAX2PLUS. Не знаю, как у xilinx, у альтеры прошивки в HEX выглядят как «много нулей, проскакивают ненули». Весьма неплохо жмутся простейшими алгоритамми типа модифицированного packbits (повторяться массово может только 0, поэтому его не нужно сохранять). Для распаковки: «если старший бит байта 0, то скопировать столько байт со входа на выход, иначе выдать на выход столько нулей, сколько записано в младших семи битах»
Или с битовой картой - берём со входа байт, идём по его битам. Если 0 — выдаём на выход нулевой байт, если 1 — копируем на выход байт со входа (© Ivan Mak).
Жмут они похуже ZIP-а, но распаковщик занимает настолько меньше места, что для меги256 может оказаться по сумме выгоднее zip.
Cyclone альтеровские уже в себе имеют распаковщик какого-то RLE и Quartus при соответствующей галке генерирует сжатый поток, у спартана3 такого нет? Впрочем, кажется, какой-то из алгоритмов для первого циклона жал лучше, чем штатный квартусовский. Зато тот можно в конфиг eeprom записать и циклон сам поймёт.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Nov 8 2010, 14:22
|
Группа: Участник
Сообщений: 9
Регистрация: 15-01-10
Пользователь №: 54 837

|
Спасибо за ответы. Цитата(MrYuran @ Nov 3 2010, 17:30)  Что мешает поставить сбоку флешку и лить из неё? То, что аппаратура уже какая есть. Цитата(ReAl @ Nov 3 2010, 18:16)  Cyclone альтеровские уже в себе имеют распаковщик какого-то RLE и Quartus при соответствующей галке генерирует сжатый поток, у спартана3 такого нет? В Spartran 3 есть сжатие битового потока, есть сжатие z для многоблочных PROM Xilinx. У меня стоит больше задача распаковать это на стороне ATmega. Буду благодарен на ссылки с алгоритмами. На счёт первого бита в байте не совсем понял -- что если он на чамом деел уже такой есть (не искуственно созданный). Цитата(rezident @ Nov 4 2010, 00:23)  У нас в похожей ситуации используется сжатие RLE, которое тут уже упоминалось. Альтернативным решением м.б использование другого (более простого/дешевого) МК и SPI Flash. Другие МК уже не поставить. RLE попробую посмотреть. Если вспомните полезные ссылки и прочее для кода на C, буду благодарен. Спасибо.
|
|
|
|
|
Nov 23 2010, 14:24
|
Группа: Участник
Сообщений: 9
Регистрация: 15-01-10
Пользователь №: 54 837

|
Использую PackBits. На машине упаковка и распаковка работают нормально. При программировании AVR, тестовый у ПЛИС светодиод не мигает, т.е. ПЛИС программируется неправильно. В чём может быть дело? Процедура программирования ПЛИС несжатой прошивкой. Код void FPGA_sendfile(uint_farptr_t buf, uint32_t buf_len) { unsigned char i; uint32_t l; uint8_t c;
for (l = 0; l < buf_len; l ++) // buf_len-1 { c = pgm_read_byte_far(buf + l); for (i = 0;i < 8;i ++) { if ((c & 0x80)>0) SET_XSP_DIN; else CLEAR_XSP_DIN; CLEAR_XSP_CLK; c<<=1; SET_XSP_CLK; } } SET_XSP_DIN; } Процедура программирования ПЛИС сжатой прошивкой. Код void FPGA_sendpackedfile(uint_farptr_t buf, uint32_t buf_len) { unsigned char i; uint32_t L; // uint8_t c;
int32_t countChar; /* run/copy count */ uint8_t c; /* current character */
L = - 1; while(L <= buf_len - 1) // - 2? { L += 1; countChar = (int32_t) pgm_read_byte_far(buf + L);
if (countChar < 0) { /* we have a run write out 2 - countChar copies */ countChar = (MIN_RUN - 1) - countChar;
L += 1;
while (countChar > 0) { c = pgm_read_byte_far(buf + L); for (i = 0;i < 8;i ++) { if ((c & 0x80)>0) SET_XSP_DIN; else CLEAR_XSP_DIN; CLEAR_XSP_CLK; c <<= 1; SET_XSP_CLK; } countChar--; } } else { /* we have a block of countChar + 1 symbols to copy */ for (countChar++; countChar > 0; countChar--) { L += 1; c = pgm_read_byte_far(buf + L);
for (i = 0; i < 8; i ++) { if ((c & 0x80)>0) SET_XSP_DIN; else CLEAR_XSP_DIN; CLEAR_XSP_CLK; c <<= 1; SET_XSP_CLK; } } } } SET_XSP_DIN; } Не пойму, где тут мог намудрить. Я прикрепил проект для тестирования упаковки/распаковки на инструментальной системе и проект для программирования целевой. Буду благодарен за советы и помощь.
|
|
|
|
|
Nov 24 2010, 12:37
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Код int32_t countChar; Зачем 32 бита? У вас максимальный счетчик - 128 Код countChar = (int32_t) pgm_read_byte_far(buf + L); if (countChar < 0) Если pgm_read_byte_far возвращает беззнаковый char то работать не будет Код countChar = (MIN_RUN - 1) - countChar; Это вообще не понял - там счетчик в чистом виде: countChar &= 0x7F;Код while (countChar > 0) { c = pgm_read_byte_far(buf + L); А вот это ошибка - мы 0 должны выводить, а не содержимое следующего байта флеша: Код while (countChar > 0) { c = 0;
|
|
|
|
|
Jan 12 2011, 06:26
|
Группа: Участник
Сообщений: 9
Регистрация: 15-01-10
Пользователь №: 54 837

|
Цитата(XVR @ Nov 24 2010, 18:37)  Код int32_t countChar; Зачем 32 бита? У вас максимальный счетчик - 128 На самом деле 129. Можно обойтись и 16-тью. Цитата(XVR @ Nov 24 2010, 18:37)  Код countChar = (int32_t) pgm_read_byte_far(buf + L); if (countChar < 0) Если pgm_read_byte_far возвращает беззнаковый char то работать не будет Как тогда быть? Что использовать вместо pgm_read_byte_far? Цитата(XVR @ Nov 24 2010, 18:37)  Код countChar = (MIN_RUN - 1) - countChar; Это вообще не понял - там счетчик в чистом виде: countChar &= 0x7F;Цитата(XVR @ Nov 24 2010, 18:37)  Код while (countChar > 0) { c = pgm_read_byte_far(buf + L); А вот это ошибка - мы 0 должны выводить, а не содержимое следующего байта флеша: Код while (countChar > 0) { c = 0; Я брал код отсюда (PackBits Variant): http://michael.dipperstein.com/rle/index.htmlНа инструментальной системе всё работает, поэтому на сам алгоритм я не особо грешу, а вот на реалтзацию для avr... Надеюсь на вашу дальнейшую помощь.
|
|
|
|
|
Jan 12 2011, 11:45
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата Как тогда быть? Что использовать вместо pgm_read_byte_far? Его и использовать. Приведение типа неправильное, должно быть countChar = (unsigned char) pgm_read_byte_far(buf + L);Цитата Я брал код отсюда (PackBits Variant) Пардон, я думал, что вы реализовали алгоритм от ReAl (он сюда подходит гораздо лучше)
|
|
|
|
|
Jan 12 2011, 17:36
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(XVR @ Jan 12 2011, 16:45)  Пардон, я думал, что вы реализовали алгоритм от ReAl (он сюда подходит гораздо лучше) Я на ACEX1K30..1K50 когда-то давно сверял, c битовой картой © Ivan Mak вроде бы чуть лучше работал. А я просто по быстрячку Macintosh PackBits модифицировал под случай, когда массово повторяться может только 0, поэтому его нет смысла и писать в выходной поток. Цитата(StanislavF @ Jan 12 2011, 11:26)  Как тогда быть? Что использовать вместо pgm_read_byte_far? У Вас в массиве во флеше записаны знаковые байты. Значит, нужно возврат pgm_read_byte_far приводить к знаковому байту. Код int8_t counter; counter = (int8_t)pgm_read_byte_far( ptr ); Я пользовался не знаковым числом, а флагом в старшем бите беззнакового 8-битного числа.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|