При миграции на новое ядро столкнулся с трудностями в работе с интерфейсом uart.
Через интерфейс UART2 принимаются данные, пакетами по 20-40 байт, 3-5 пакетов в секудну. Корректность данных проверяется по контрольной сумме, предусмотренной в протоколе пакета.
Приложение принимающее данные написано с использование Qt, попытки чтения данных происходят с частотой 50 Гц в отдельном потоке с высоким приоритетом.
Настройки соединения: 8 бит данных, 1 стоповый бит. Приём данных тестировался на скоростях до 4000000 bps.
Всё это хорошо работало на ядре версии 3.0.35_4.1.0, которое было на виртуальной машине с ftp сервера starterkit.
Далее система мигрировала на ядро версии 3.10.17_1.0.2, которое шло в комплекте с buildroot-2014.08-sk, выложенное тут недавно. В этой версии ядра новый драйвер UART интерфейса "drivers/tty/serial/imx.c". И с этим драйвером следующая проблема:
На скоростях соединения больше 115200 bps периодически возникает ошибка: "imx-uart 21e8000.serial: Rx FIFO overrun". Это происходит в произвольный момент времени и через произвольное число принятых байт(раз в несколько секунд). При этом наблюдается потеря принимаемых данных. Если приём производить не через UART2 а через USB переходник(FT232 и, соответсвтенно, его драйвер), то передача данных происходит корректно на любых доступных скоростях( до 2000000 bps). В исходниках драйвера видно, что ошибка выводится при проверке флага USR2_OR/* Overrun error */. В старой версии драйвера этой проверки не было, но если и в новой версии убрать проверку, сообщения не выводятся, но проблема остаётся. Помимо флага USR2_OR, выставляется также флаг URXD_OVRRUN.
Вот
файл конфигурации платы.
В общем виде открытие порта производится следующим образом:
fd = open("/dev/ttymxc%1", O_RDWR | O_NOCTTY | O_NDELAY);
tcgetattr(fd, &trm);
trm.c_iflag=0;
trm.c_oflag=0;
trm.c_cflag=cs|CREAD|CLOCAL;
trm.c_lflag=0;
trm.c_cc[VMIN]=1;
trm.c_cc[VTIME]=0;
cfsetspeed(&trm, B2000000);
fcntl(fd, F_SETFL, FNDELAY);
tcsetattr(fd, TCSANOW, &trm)
Общий вид работы потока чтения:
while(!stop_flag)
{
rec_bytes = read(fd, buf, 512);
msleep(20);
}
Если в качетве отладочной информации выводить число принятых байт(rec_bytes выше), то видно, что принимаются данные пакетами по 20-40 байт 3-5 пакетов в секудну, то есть с запасом хватает и буфера и частоты опроса. Но как работает драйвер мне совсем не очевидно, поэтому прошу помощи.