Проблема с UART на ядре 3.10.17_1.0.2.
DeD |
|
|
|
|
|
|
|
Пункты: 393 |
Регистрация: 27.02.2012 |
|
|
|
Я включил RTS/CTS:
trm.c_iflag= IGNPAR;
trm.c_oflag=0;
trm.c_cflag= baud | CRTSCTS | cs | CLOCAL | CREAD;
trm.c_lflag=0;
trm.c_cc[VMIN]= 1;
trm.c_cc[VTIME]=0;
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&trm);
Но это не помогает, ошибки "FIFO overrun" продолжают появляться. Особенно часто эти сбои наблюдаются, если параллельно идёр работа с SD картой(запись, например). |
|
|
|
|
|
vladch |
|
|
|
|
|
|
|
Пункты: 60 |
Регистрация: 02.02.2015 |
|
|
|
"FIFO overrun" возникает при переполнении буфера RX FIFO(32 байта). Например, на скорости 115200 бит/с он заполнится за 3,2 мс, если прерывания по UART не могут выполнится вовремя, в связи с тем, что какой-то драйвер их заблокировал. У меня например есть «подвисания» до 2 мс при переключении окон , запуске программ и высокой загрузки системы – не выполняются вовремя прерывания по UART и hrtimer.
1.Можно попробовать задействовать SDMA – необходимо покопаться в драйвере drivers/tty/serial/imx.c, там он в принципе реализован, но ему необходим RTS/CTS.
Для своих целей поправил SDMA для работы без RTS/CTS, в принципе все работает. Но выяснилось что при использовании 9-битного формата (RS-485 Mode) SDMA некорректно работает(воспринимает 9-бит как ошибку), необходимо править микрокод контроллера SDMA.
2.Переключение обработки прерываний по Uart на другое ядро процессора не помогло, хотя на форумах рекомендуют.
3.Рекомендуют перевести нужные прерывания на FIQ вместо IRQ, они должны обрабатываться вне очереди, и прерывать другие прерывания. Вроде так сделано в /sound/soc/fsl/imx-pcm-fiq.c
4.Лучше всего выяснить откуда такие «подвисания» системы.
На данный момент (ядро 3.0.35 и 3.10.17) ограничился пакетами запрос/отклик не более 32 байт, скорость 500 кбит/с, одновременный обмен по 4 uart, цикл обмена с 20 абонентами по одному порту- 10мс, суммарный объем данных 40Кб/сек на порт, - работает отлично. После перехода на новое ядро 3.10.53 планирую разобраться с п.3 и п.4. |
|
|
|
|
|
DeD |
|
|
|
|
|
|
|
Пункты: 393 |
Регистрация: 27.02.2012 |
|
|
|
Спасбо, всё стло яснее. Я вот включал RTS/CTS, а это ж физические линии, и у меня их нет. Можно поподробнее про SDMA без RTS/CTS, как это сделать? |
|
|
|
|
|
vladch |
|
|
|
|
|
|
|
Пункты: 60 |
Регистрация: 02.02.2015 |
|
|
|
Инициализируется SDMA только по данном условиям:
if (termios->c_cflag & CRTSCTS) {
if (sport->have_rtscts) {
ucr2 &= ~UCR2_IRTS;
ucr2 |= UCR2_CTSC;
/* Can we enable the DMA support? */
if (is_imx6q_uart(sport) && !uart_console(port)
&& !sport->dma_is_inited)
imx_uart_dma_init(sport);
}
}
Описание битов:
UCR2_CTSC =1. When the RxFIFO is filled to the level of the programmed trigger level and the start bit of the overflowing character (TRIGGER LEVEL + 1) is validated, the CTS_B output pin is negated to indicate to the far-end transmitter to stop transmitting.
UCR2_IRTS =0. Transmit only when the RTS pin is asserted
Для работы без RTS/CTS переделал инициализацию порта и запуск RX DMA. Вместо запуска RX DMA (start_rx_dma()) после прихода 1 байта запустил его уже в imx_set_termios , а в dma_rx_callback() его никогда не останавливаю, а перезапускаю. Прерывание dma_rx_callback происходит по заполнению буфера DMA или при паузе в приеме 4-32 байта.
У меня драйвер полностью переделан – обмен с устройствами происходит полностью в драйвере (включая проверку формата пакета и контрольной суммы), а уже результат в программу передается одним пакетом на все устройства.
Кстати если посмотреть драйвер в ядре 3.10.53 - он там уже немного оптимизирован:
ENGR00329822-04 tty: serial: imx: optimize the rx performance
Optimize the uart rx performance that use SDMA loop mode instead
of normal mode. After the changes, uart rx fifo overrun issue disappear
even if hw flow control is disabled. |
|
|
|
|
|
|