Вот кусок рабочего кода: (+)
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено ПВ 17 апреля 2004 г. 07:04
В ответ на: Помогите разобраться с "Boot Loader Support – Read-While-Write Self-Programming" отправлено Wild_A 16 апреля 2004 г. 18:47

Конкретно, что не понятно? В даташите на Мегу 128 все расписано нормально. Вот мой работающий кусок - вначале идет всякая преамбула, потом (с которого начинается приведеная вставка) - загрузка 2х байт длины массива (В СЛОВАХ!!!) потом такой финт - прием байт ведется по прерываниям в приемный буфер УАРТА (векторы перенесены в бут-сектор), причем если до конца буфера остается меньше 20-ти байт, RTS сбрасывается, тормозя порт. Когда основная прога выгребает данные, и буфер освобождается более, чем на 60 байт - RTS взводится вновь. rx_counter - сколько байт в приемном буфере УАРТа. page_buffer - буфер для программирования флеша. Ну далее все понятно, я думаю (если и щас непонятно - тогда не стОит и продолжать ;-))

Преимущества прерываний: буфер страницы 256 байт (128 слов) при скорости 115200 бод заполняется за 22мс. А запись страницы флеша - 4мс на стирание + 4мс на саму запись, + пару-тройку мс на всякие заполнения-проверки, т.е. примерно 10мс. Получается прочессы закачки данных и записи их во флеш идут параллельно, СОМ-порт "дует" данные непрерывно. Если б скорость СОМ-порта писюка поднять до 230400 - очень красяво бы вышло, 11 мс страница, или вся 128-я Мега за 1,5 секунды! (Ау, ISP-шники?... :-))))

(да и сейчас неплохо)

(Примечание - если код подпортится из-за всяких "тегов" - я не виноват. Среда - ИАР 3.10С)


// Принята синхропоследовательность + 'F'. Загрузка данных
// и программирование FLASH

data_counter = 0;
data_lenth = 0; // in WORDS!!! (0000-F000)
if ((tempint = Receive_Byte_UDR1()) & (1<<(FE1+8))) Fatal_Error();
data_lenth |= (unsigned int)((char)tempint);
if ((tempint = Receive_Byte_UDR1()) & (1<<(FE1+8))) Fatal_Error();
data_lenth |= ((unsigned int)((char)tempint)<<8);

if (data_lenth >= 0xF000) Fatal_Error(); // нельзя писАть в BootSector!

// теперь прием в прерываниях по RXC1
// Enable RXC1 Interrupt
UCSR1B = (1< __enable_interrupt();

tempchar = 0; // количество записанных в буфер страницы байт
flash_address = 0; // адрес следующей (0) страницы в словах
RAMPZ = 0; //RAMPZ = 0 (все начинается с нулевой страницы)

while (data_counter != data_lenth) // цикл записи во FLASH
{
while (buffer_head == buffer_tail); // ждать, если нечего записывать
page_buffer[tempchar++] = input_buffer[buffer_tail++];
while (buffer_head == buffer_tail); // ждать, если нечего записывать
page_buffer[tempchar++] = input_buffer[buffer_tail++];
__disable_interrupt();
if ((rx_counter -= 2) < (0xFF-60))
{
PORTD &= ~(1< PORTF = 0x77;
}
__enable_interrupt();
data_counter++; // in WORDS!!!
if (tempchar) continue; // если страница не заполнена полностью
// Запись!
write_flash_page (); //RAMPZ + flash_address + page_buffer[256] !
flash_address = data_counter<<1; // адрес следующей страницы в словах
RAMPZ = (char)(data_counter>>15);
}

if (tempchar) // остались байты?
{
while (tempchar)
{
// дозаполнить страницу 0xFF
page_buffer[tempchar++] = 0xFF;
page_buffer[tempchar++] = 0xFF;
}
write_flash_page (); //RAMPZ + flash_address + page_buffer[256] !
}

// загрузка FLASH окончена - беск. цикл и

Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru