|
Простой вопрос про Nios II UART, почему теряет байты? |
|
|
|
Apr 27 2011, 15:56
|
Местный
  
Группа: Свой
Сообщений: 399
Регистрация: 1-01-06
Из: Волгоград
Пользователь №: 12 763

|
Собственно, добрался до минимальной глючащей программы. Код #include "unistd.h" #include "fcntl.h" #include "stdio.h" #include "system.h" #include "sys/alt_irq.h"
int main (void) { int uart_descriptor;
alt_u32 i, timer; alt_u8 command = 0x85; alt_u32 recieved;
alt_irq_context aaa;
printf ("Vezuviy UART Test Program");
uart_descriptor = open ("/dev/uart_board_0", O_RDWR|O_NONBLOCK|O_NOCTTY|O_SYNC); if (uart_descriptor) { printf ("Device_open success!\n");
while (1) { timer = alt_nticks (); write (uart_descriptor, &command, 1); recieved = 0;
while (alt_nticks() < (timer + 100) && (recieved != 95)) { tmp = read (uart_descriptor, NULL, 1000); if (tmp > 0) recieved += tmp; }
printf ("%ld\n", recieved);
}
} else printf ("Device_open fail!\n");
} Есть устройство, которое подключено к NIOS по UART, в ответ на команду запроса оно возвращает ответ - ровно 95 байтов (проверено, 100%). А Nios почему-то иногда получает меньше. Теряется случайный байт в середине пакета, либо несколько байт подряд. Если перестать постоянно пытаться забрать имеющиеся данные из буфера, а подождать некоторое время а потом прочитать, то данные всегда приходят целыми. Т.е. такой код работает: Код while (1) { timer = alt_nticks (); write (uart_descriptor, &command, 1); recieved = 0;
while (alt_nticks() < (timer + 100) ) ;
recieved = read (uart_descriptor, NULL, 1000);
printf ("%ld\n", recieved);
} Зы, система простая, содержит несколько UART, один системный таймер, PIO и epcs_controller. В BSP выбраны полные не уменьшенные быстрые драйвера для UART.. (работающие через прерывания) Корявый драйвер не запрещает прерывания при чтении? Или я что-то делаю не так?
|
|
|
|
|
Apr 28 2011, 16:00
|
Местный
  
Группа: Свой
Сообщений: 399
Регистрация: 1-01-06
Из: Волгоград
Пользователь №: 12 763

|
Продолжение.. После исключения JTAG UART и возврата к большой программе потери байтов повторились. При прогоне кода в самом начале топика я добавил счетчик - а сколько раз он успевает вызвать read. Оказалось что всего 64 раза. Т.е. выходит что большую часть времени процессор находился в прерывании. Суть - он тормоз, uart на 115200 для него уже почти предел ) программа исполняется из SDRAM, процессор средний - NiosII/e, частота 54 МГц. Не думал что это будет настолько медленно... В общем замена процессора на NiosII/f помогла и байты теряться перестали (как я понимаю, процедура прерывания стала попадать в кэш и исполняться быстро). Так что все-таки правильным был вариант "я что-то делаю не так", vadimuzz, как всегда точен  А как бы вы оценивали сколько процентов времени процессор проводит в прерывании? зы. теперь понимаю почему гугль так часто выдавал мне темы про Fifo-ed UART..
|
|
|
|
|
Apr 28 2011, 16:06
|

Лентяй
     
Группа: Свой
Сообщений: 2 203
Регистрация: 11-10-04
Из: Санкт-Петербург
Пользователь №: 843

|
Цитата(Reanimator++ @ Apr 28 2011, 20:00)  ... программа исполняется из SDRAM, процессор средний - NiosII/e, частота 54 МГц. Не думал что это будет настолько медленно... NiosII/e - это минимальная конфигурация (Economy), это действительно тормоз, особенно с прерываниями (кстати, для саморазвития почитайте, как там организована обработка прерываний  ). Средняя конфигурация называется Standard, и, соответственно, /s. А если используете Fast, то имеет смысл добавить VIC - тогда с прерываниями вообще хорошо станет.
--------------------
Чтобы слова не расходились с делом, нужно молчать и ничего не делать...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|