Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AT91SAM7S128: Реализация вывода на DBGU средствами PDC
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
vet
Идея такова: моя процедура (putchar) подкладывает символы в кольцевой буфер, контроллер ПДП их оттуда забирает. Написал код, но по непонятной мне причине работает он нестабильно - попечатает немного и виснет. Без использования ПДП вывод работает нормально. Что может быть тому причиной?
Код прилагается. Работает всё это дело под uCOS-II.
Код
char DbgTxPDCBuf[256];                             //область под буферы ПДП

void DBG_putcharPDC(unsigned char c) {
  AT91PS_PDC base = AT91C_BASE_PDC_DBGU;

  base->PDC_PTCR = AT91C_PDC_TXTDIS;               //запретить ПДП
  if (base->PDC_TNCR==0) {                         //если сл.буфер пуст,
    char *pEnd1 = (char*)base->PDC_TPR;
    pEnd1 += base->PDC_TCR;                        //адрес 1-го незанятого байта за главным буфером
    if (pEnd1<DbgTxPDCBuf+sizeof(DbgTxPDCBuf)) {   //если за ним еще есть свободное место,
      *pEnd1 = c;                                  //дописать символ в главный буфер
      base->PDC_TCR++;
    }
    else if (base->PDC_TCR!=(INT32U)DbgTxPDCBuf) { //если за главным буфером нет свободного места,
      base->PDC_TNPR = (INT32U)DbgTxPDCBuf;        //делаем сл.буфер в начале области
      base->PDC_TNCR = 1;                          //и дописываем в него символ
      DbgTxPDCBuf[0] = c;
    }
    //иначе - буфер №1 заполняет всю область, пропустить символ
  }
  else {                                           //если сл.буфер не пуст,
    char *pEnd2 = (char*)base->PDC_TNPR;
    pEnd2 += base->PDC_TNCR;                       //адрес 1-го незанятого байта за сл.буфером
    if ((INT32U)pEnd2<base->PDC_TPR) {             //если за ним еще есть свободное место,
      *pEnd2 = c;                                  //дописать в него символ
      base->PDC_TNCR++;
    }
    //иначе - главный и сл.буферы заполняют всю область, пропустить символ
  }
  base->PDC_PTCR = AT91C_PDC_TXTEN;                //разрешить ПДП
}


Инициализация:
Код
  AT91F_PDC_Open(AT91C_BASE_PDC_DBGU);
  *AT91C_DBGU_PTCR = AT91C_PDC_TXTEN;

Прерывания по событиям ПДП запрещены.
vet
Поправка: 14-я строка на самом деле выглядела так:
Код
else if (base->PDC_TPR!=(INT32U)DbgTxPDCBuf) { //...

но зависаний (Data Abort) это не устранило.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.