Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: USART PDC переключение областей памяти
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Goofy
У меня это организовано так:

Код
void ProcessUpLinkIncomingMessages(void)
{
unsigned int rcr=pDataLinkPDC->PDC_RCR;
if ( rcr==UPLINK_BUFFER_SIZE ) return;

switch (BufferSemaphore)
    {
    case PRIMARY:

        AT91F_PDC_SetRx(pDataLinkPDC,UpLinkRXBufferSec,UPLINK_BUFFER_SIZE);
        ProcessMessages (UpLinkRXBufferPri,(unsigned short)(UPLINK_BUFFER_SIZE-rcr),UpLinkPayLoadBuffer, &UpLinkMessageState);
        BufferSemaphore=SECONDARY;

        break;
    case SECONDARY:

        AT91F_PDC_SetRx(pDataLinkPDC,UpLinkRXBufferPri,UPLINK_BUFFER_SIZE);
        ProcessMessages (UpLinkRXBufferSec, (unsigned short)(UPLINK_BUFFER_SIZE-rcr),UpLinkPayLoadBuffer, &UpLinkMessageState);
        BufferSemaphore=PRIMARY;

        break;
    }

}

Процедура вызывается 100 раз в секунду. Бод рейт 57600, UPLINK_BUFFER_SIZE=256
Пакеты идут плотно, разной длины, проверяется контрольная сумма в конце пакета.
Условия "тепличные", пакеты теряются. Хочу исключить (или подтвердить) то опасение, когда байт теряется от переключения буферов. Похорошему нужно задействовать RNPR RNCR, но тут сразу вопрос: как грамотно переключиться обратно на первоначальные счётчики RPR, RCR и не потерять данные ? Или опасения мои пустые вовсе?

забыл чип указать: sam7s
sergeeff
Чтобы ничего не терялось и сделаны два буфера с DMA. У Atmela был пример всего этого : AT91RM9200-BasicUSARTPDC-GHS3_6-2_0.
aaarrr
Цитата(Goofy @ Apr 2 2008, 22:55) *
Похорошему нужно задействовать RNPR RNCR, но тут сразу вопрос: как грамотно переключиться обратно на первоначальные счётчики RPR, RCR и не потерять данные ? Или опасения мои пустые вовсе?

Опасения пустые: значения из RNPR и RNCR копируются в RPR и RCR автоматом, т.е. в прерывании по ENDRX нужно просто записать данные нового буфера в RNPR и RNCR.
Goofy
Цитата(aaarrr @ Apr 3 2008, 03:35) *
Опасения пустые: значения из RNPR и RNCR копируются в RPR и RCR автоматом, т.е. в прерывании по ENDRX нужно просто записать данные нового буфера в RNPR и RNCR.


Спасибо за информацию! Стабильность возросла, но ликвидирована не последняя причина потерь пакетов.
Решил обойтись без прерывания, PDC пишет всегда в один буфер, перескакивая на его начало, обработка "догоняет" запись при каждом вызове:

Код
if (pPDC->PDC_RNCR)
    {  // same buffer session
    if (BytesLeft>rcr) ProcessMessages (RXBufferPri+(BUFFER_SIZE-BytesLeft),(BytesLeft-rcr),PayLoadBuffer, &MessageState);
    BytesLeft=rcr;
    }
else
    {  //new one
    ProcessMessages (RXBufferPri+(BUFFER_SIZE-BytesLeft), BytesLeftFromPast ,PayLoadBuffer, &MessageState);
    AT91F_PDC_SetNextRx (pPDC,RXBufferPri,_BUFFER_SIZE);
    BytesLeft=BUFFER_SIZE;
    }
aaarrr
ИМХО, очень странный метод работы. Чем прерывания-то не угодили?
Goofy
Цитата(aaarrr @ Apr 4 2008, 02:28) *
ИМХО, очень странный метод работы. Чем прерывания-то не угодили?


Данный код достаточен. Достаточен в тех условиях что буффер не заполнится гарантировано между вызовами. А если достаточен зачем делать больше?...
sergeeff
Цитата(Goofy @ Apr 3 2008, 22:44) *
Данный код достаточен. Достаточен в тех условиях что буффер не заполнится гарантировано между вызовами. А если достаточен зачем делать больше?...

Странноватый подход. Чем прерывания то не угодили? Странно, что второй буфер не заполняется. Ведь есть вероятность того, что во время обработки данных из первого могут придти еще данные. Собственно для предотвращения такой ситуации связанные буфера и были придуманы.

Теперь по делу. Если не секрет - что за процессор? Не с кэшом ли часом?
defunct
Цитата(sergeeff @ Apr 3 2008, 21:22) *
Теперь по делу. Если не секрет - что за процессор? Не с кэшом ли часом?

SAM7S см. самый первый пост.

Цитата
Данный код достаточен.

раз теряются данные, то видать недостаточен.

Я поступил бы так:
По прерыванию DMA, постановка текущего принятого буфера в очередь на обработку, там же в прерывании выделение буфера для сл. пакета и подзагрузка DMA next указателя.

В основном теле программы - проверка очереди пакетов,
обработка и освобождение.
Goofy
Цитата(defunct @ Apr 4 2008, 06:12) *
SAM7S см. самый первый пост.
раз теряются данные, то видать недостаточен.

Я поступил бы так:
По прерыванию DMA, постановка текущего принятого буфера в очередь на обработку, там же в прерывании выделение буфера для сл. пакета и подзагрузка DMA next указателя.

В основном теле программы - проверка очереди пакетов,
обработка и освобождение.



Теряются пакеты из за других косяков. А именно когда идут пакеты разного типа. Когда идёт один тип, всё отлично (очевидно проблемы в обработке) Второй буфер заполняется, но фактически это тот же адрес. То есть циклически пишем в один и тот же буффер обрабатывая поступающие данные в догонку убывающему RCR. Нет нужды в прерываниях, лишних массивах, аллоцировании памяти, флагах заполнения

вот подкорректированый код, если внимательно посмотреть, ряд вопросов пропадёт
Код
{
if (!pPDC->PDC_RNCR)
//Анализируется, не выполнено ли первоначальное заполнение буфера, когда RNCR обнулиться.
//Если да, то дочитывается "хвост" образовавшийся в момент переключения PDC c RPR  на RNPR, нопроцедурой не обработанный


    {  
    ProcessMessages (RXBufferPri+(BUFFER_SIZE-BytesLeft), BytesLeft ,PayLoadBuffer, &GPSMessageState);
//назначается следующий принимающий буффер (те же адреса уже обрабатываются в RPR и RCR)
    AT91F_PDC_SetNextRx (pPDC,RXBufferPri,BUFFER_SIZE); //не SetRx!
    BytesLeft=BUFFER_SIZE; //сбрасывается число недочитанных байт

    }

//Если чило оставшихся непрочитанных байт BytesLeft меньше числа записанных rcr
// то обрабатываем разницу с соответсвующим смещением
    if (BytesLeft>rcr) ProcessMessages (RXBufferPri+(BUFFER_SIZE-BytesLeft),(BytesLeft-rcr),PayLoadBuffer, &MessageState);
    BytesLeft=rcr;

}


частота вызова строго 100Гц
размер буфера 256
при бод рейте 57600 наложение ещё не прочитанных данных вновь пришедшими исключено
Goofy
Процесс полностью отлажен, последние проблемы были в ProcessMessages.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.