реклама на сайте
подробности

 
 
> AT91RM9200 XModem Баг, в примерах от Atmel Баг!
cf7k
сообщение Jan 25 2007, 03:06
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 82
Регистрация: 14-03-06
Из: Санкт-Петербург
Пользователь №: 15 227



Вот накушался. Может кому-то спасет много времени.

Вводная: копался с XModem Service... надо было передать по XModem маленький файлик размером не более 528 байт (страница dataflash). вобщем и частном можно рассматривать пример AT91RM9200-BasicROM_Services-ARM1_2-2_0.zip.

все вроде бы хорошо (акцентирую внимание на нужных кусках кода):
Код
AT91S_SBuffer    sXmBuffer;
AT91S_Pipe    xmodemPipe;
AT91S_SvcXmodem    svcXmodem;

// "Tempo" Service
AT91S_CtlTempo           ctlTempo;

.....

void AT91_XmodemProtocol(AT91S_PipeStatus status, void *pVoid)
{
    AT91PS_USART  pUsart     = svcXmodem.pUsart;
            
    svcXmodem.tempo.Start(&(svcXmodem.tempo), 10, 0, AT91_XmodemComplete, pUsart);                                
}


Вроде все логично: сначала tempo сервис от XModem'a используется для посылки "C" ежесекундно, как только начинается прием - он не нужен - соответственно он в дальнейшем используется для ожидания окончания обмена (прихода символа EOT).

Поведение: файлик принимается правильно, но основная прога наглухо застревает в while (EndOfTransmission != 1);

Код
    xmodemPipe.Read(&xmodemPipe, (char *) Buffer_Xmodem, MEMORY_SIZE_MAX, AT91_XmodemProtocol, (void *) Buffer_Xmodem);
    while (EndOfTransmission != 1);


и не попадает в заветный,

Код
void AT91_XmodemComplete(AT91S_PipeStatus status, void *pVoid)
{
    // stop the Xmodem tempo
    svcXmodem.tempo.Stop(&(svcXmodem.tempo));
    
    // upload complete
    EndOfTransmission = 1;
}

который его выведет из этого цикла

А вся фича в том, что при получении прерывания (вызове из IRQ.SYSTEM_INTERRUPT svcXModem.Handler) по приему символа (RXRDY) - стопорится XModem'овский tempo таймер.

----------------------
xmodemPipe.Read(...)
----------------------
посылка символов "C"
----------------------
INT на символ RXRDY(SOH): svcXModemHandler.Handler (он же svcXModemReadHandler)
остановка svcXModem.tempo
настройка прерываний на PDC
----------------------
...
----------------------
INT PDC: svcXModemHandler.Handler (он же svcXModemReadHandler)
FillRdBuffer()
если принято все что должно было прийти(нет места для приема) - вызов callback (а это заветный AT91_XmodemProtocol), который запускает svcXmodem.tempo!!!!
настройка прерываний на символ
----------------------
INT на символ (наглядно увидеть EOT):
И вот svcXModem.tempo стопорится. символ EOT пришел, а таймер, который его ждет и хотит об это сообщить в callback, убит этим пришедшим символом.
Далее можно бесконечно ждать while (EndOfTransmission != 1);
(так сказать "мордой об асфальт перед финишной чертой" smile.gif )
----------------------

Лекарство:
для ожидания окончания приема добавить в сервис CtlTempo еще один софтовый таймер SvcTempo и его ждать. Самый дешевый и экономный по памяти и по коду способ. (можно еще перекрыть SvcXModem.Handler и отслеживать "чужой" таймер в SvcXModem.tempo... но все это от лукавого)

Код
AT91S_SvcTempo svcTempoWaitX;
....
ctlTempo.CtlTempoCreate(&ctlTempo, &svcTempoWaitX);
...

void AT91_XmodemProtocol(AT91S_PipeStatus status, void *pVoid)
{
    svcTempoWaitX.Start(&svcTempoWaitX, 10, 0, AT91_XmodemComplete, (void*) 0);    
}

void AT91_XmodemComplete(AT91S_PipeStatus status, void *pVoid)
{
    // не перезагружаемый таймер сам остановится!!!
    
    EndOfTransmission = 1;
}


Все. иду спать blink.gif
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- cf7k   AT91RM9200 XModem Баг   Jan 25 2007, 03:06


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 15:21
Рейтинг@Mail.ru


Страница сгенерированна за 0.01431 секунд с 7
ELECTRONIX ©2004-2016