ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Суббота
23 ноября
740383 Топик полностью
vpv.vpv (02.03.2017 10:07, просмотров: 320) ответил Adept на бутлодырь...
1. Стрим с UART'а загоняется в большой кольцевой буфер (сколько там RAM есть у камня) по прерываниям от приемника. Поток останавливается/пускается по сигналам RTS/CTS, для этого у тех же МАХ232 есть 2 приемника и 2 передатчика TTL <-> RS232. Нужен ещё таймер в своем прерывании, как только таймер увидел, что буфер на 1/3 освободился - активирует CTS, как только приемный буфер UART видит, что он заполнился - он этот CTS сбрасывает. 2. Основная программа выгребает порциями данные из большого приемного буфера в буфер страницы и программирует флеш. Пока данные не кончатся. 3. Все время подсчитывается CRC. Если в конце оно совпадает - CRC дописывается, формируются флажки "Programm done" ну или у кого там что. :)) иначе - ошибка. Основная идея - прием данных с UART сделать автоматическим, в прерываниях, а программированием флеша заняться вручную, по опросу готовности. Хотя, наверное, можно и наоборот. :)) Если интересно, кусок программирования для Меги128 у меня когда-то выглядел вот так (компилятор Си - IAR AVR. За стиль написания не пинать, давно это было :)) //------------------------------------------------------------------------ // Если тип прошивки "F", то программирование FLASH if (cProgType == 0x0F) { unsigned int iword; unsigned char __hugeflash* pcfpointer; unsigned char __hugeflash* pcflenth; unsigned char __hugeflash* pcfcounter = 0; pcflenth = (unsigned char __hugeflash*) lProgLenth; if ((!pcflenth) || (pcflenth > (unsigned char __hugeflash*)0x1E000)) ShowFatalError(6); // Длина данных неверна //------------------------------------------------------------------------- while(pcflenth) // пока есть данные для программирования { pcfpointer = pcfcounter; // начать новую страницу while (SPMCSR & (1<<SPMEN));// Ожидание готовности SPM; __disable_interrupt(); __AddrToZ24ByteToSPMCR_SPM // стереть страницу ((unsigned char __farflash*)pcfpointer, (1<<PGERS)+(1<<SPMEN)); __enable_interrupt(); // *********************************************************************** do // заполнять страницу... { iword = (unsigned int) cDecryptByte(); pcflenth --; if (pcflenth) { iword |= ((unsigned int) cDecryptByte())<<8; pcflenth --; } while (SPMCSR & (1<<SPMEN)); // Ожидание готовности SPM; __disable_interrupt(); __AddrToZ24WordToR1R0ByteToSPMCR_SPM // записать слово в буфер страницы ((unsigned char __farflash*)pcfcounter, iword, (1<<SPMEN)); __enable_interrupt(); pcfcounter += 2; // переместить указатель if (!pcflenth) break; // если заполнять больше нечем, то выйти } while ((unsigned char)pcfcounter); // ... до границы страницы // *********************************************************************** while (SPMCSR & (1<<SPMEN)); // Ожидание готовности SPM; __disable_interrupt(); __AddrToZ24ByteToSPMCR_SPM // записать страницу ((unsigned char __farflash*)pcfpointer, (1<<PGWRT) | (1<<SPMEN)); __enable_interrupt(); } //------------------------------------------------------------------------ // ---------------- программирование FLASH закончено ----------------- while (SPMCSR & (1<<SPMEN)); // Ожидание готовности SPM; __disable_interrupt(); __DataToR0ByteToSPMCR_SPM // разрешить RWW секцию (0, (1<<RWWSRE)+(1<<SPMEN)); __enable_interrupt(); while (SPMCSR & (1<<SPMEN)); // Ожидание готовности SPM; // прием CRC-32 *((unsigned char*)&lProgCrc32 ) = cDecryptByte(); *((unsigned char*)&lProgCrc32 +1) = cDecryptByte(); *((unsigned char*)&lProgCrc32 +2) = cDecryptByte(); *((unsigned char*)&lProgCrc32 +3) = cDecryptByte(); // записать новую сигнатуру в EEPROM lE2ProgCrc32 = lProgCrc32; lE2ProgLenth = lProgLenth; // подсчитать CRC-32 записанного FLASH и сравнить { unsigned long ltemp = 0; unsigned char __hugeflash* pcHFpoint = 0; unsigned char __hugeflash* pcflenth = (unsigned char __hugeflash *) lProgLenth; while (pcflenth--) ltemp = lCrc32Table [(ltemp >> 24) ^ *pcHFpoint++] ^ (ltemp << 8); if (ltemp != lProgCrc32) ShowFatalError(8); // не совпадает загруженная CRC-32!!! } ShowOk(); } "cDecryptByte();" - это выгребание байта из приемного буфера с дешифрацией.