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

 
 
> Keil RTX-kernel и прием/передача по UART, Как лучше организовать взаимодействие?
Shein
сообщение Feb 27 2011, 14:40
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 45
Регистрация: 4-03-07
Пользователь №: 25 855



Доброго времени суток!
Есть проект с использованием RTX-kernel. Нужно организовать прием/передачу данных по UART. Т.к. скорости маленькие 4800/9600, то хочется снизить время бесполезного простоя системы в ожидании готовности приемника или передатчика - есть масса другой работы по обработке данных. Вот раздумываю как это сделать правильнее, красивее, с точки зрения RTOS.

С приемом, в общем, более-менее понятно. Включены прерывания по приему символа (ПДП пока не используется) и в обработчике принятый символ через mailbox отправляется задаче обрабатывающей прием.

Передачу, на данный момент сделал так:
Разрешил прерывания по готовности передатчика, в обработчике прерывания устанавливается событие "передатчик готов", а уже задача, ответственная за передачу, по этому событию пишет данные в буфер UART'a.
Минусы: обработчик прерывания один. Поэтому, когда нет данных для передачи, но идет прием, обработчик прерывания вызванный приемником, ставит и событие готовности передатчика (бит в статусе USART TXRDY ведь установлен). При этом получается что будет установка уже установленного события. Есть ли тут криминал, не знаю. В доках по этому поводу ничего не нашел.

Рассматривал вариант организации передачи тоже через mailbox. Во-первых мне показалось это излишним усложнением. во-вторых, обработчик прерывания вызывается при освобождении передатчика. А если данные появились позже?

Ну и третий вариант, просто сделать задачу передачи с низшим приоритетом, и просто пулингом ждать освобождения передатчика, без прерываний. Другие задачи будут ее о необходимости прерывать. Уж совсем как-то некрасиво, да и задача передатчика не самая низшая по приоритетности.

В общем, интересно, кто какие подходы использует?

Не думаю что это имеет значение, но на всякий случай, контроллер AT91SAM7X...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Vichkins
сообщение Feb 28 2011, 06:37
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 11-02-09
Пользователь №: 44 714



вот как сделано у меня, прерывания для передачи не используются, только для приёма
контроллер у меня lpc1343, но я думаю под ваш допилить можно

переменные:
Код
static char recvbuf[256];
static char sendbuf[256];
static U8 txridx=0;
static U8 txwidx=0;
static U8 rxridx=0;
static U8 rxwidx=0;
OS_TID t_UARTTxTask;
OS_TID t_UARTRdTask;
__task void uartTXTask(void);

и остальное
Код
void UART_SendData(char Data)
{
    sendbuf[txwidx++]=Data;
    os_evt_set (OS_FLAG_UART_TXDATAPENDING, t_UARTTxTask);  
}

uint8_t UART_ReceiveData(void)
{
  if (rxridx == rxwidx) {
      t_UARTRdTask = os_tsk_self ();
      os_evt_wait_or (OS_FLAG_UART_RECEIVED, 0xffff);
        os_evt_clr (OS_FLAG_UART_RECEIVED, t_UARTRdTask);
  }
  return (recvbuf[rxridx++]);
}

uint8_t UART_DataAvailable(void)
{
  uint8_t tmp = rxwidx    - rxridx;
    return tmp<0?256-tmp:tmp;
}


__task void uartTXTask (void) {
  while(1) {
    os_evt_wait_or(OS_FLAG_UART_TXDATAPENDING, 0xffff);
        while(txridx<txwidx)
        {
          LPC_UART->THR = sendbuf[txridx++] & UART_THR_MASKBIT;
            while (!(LPC_UART->LSR & UART_LSR_THRE));
        }
        os_evt_clr(OS_FLAG_UART_TXDATAPENDING, t_UARTTxTask);
    }
}


void __irq UART_IRQHandler(void)
{
    uint8_t ch;

    if (LPC_UART->IIR & UART_IIR_INTID_MASK == UART_IIR_INTID_RDA){
        ch = (uint8_t)(LPC_UART->RBR & UART_RBR_MASKBIT);
    recvbuf[rxwidx++]=ch;
        isr_evt_set (OS_FLAG_UART_RECEIVED, t_UARTRdTask);
    }
    
    NVIC_ClearPendingIRQ(UART_IRQn);
    return;
}


Сообщение отредактировал Vichkins - Feb 28 2011, 06:42
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 5th August 2025 - 19:32
Рейтинг@Mail.ru


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