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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Простой вопрос про Nios II UART, почему теряет байты?
Reanimator++
сообщение Apr 27 2011, 15:56
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 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.. (работающие через прерывания)

Корявый драйвер не запрещает прерывания при чтении?
Или я что-то делаю не так?
Go to the top of the page
 
+Quote Post
vadimuzzz
сообщение Apr 28 2011, 02:40
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 291
Регистрация: 21-07-05
Пользователь №: 6 988



Цитата(Reanimator++ @ Apr 27 2011, 22:56) *
Корявый драйвер не запрещает прерывания при чтении?
Или я что-то делаю не так?

скорее второй вариант. вряд ли так часто дергать read безопасно. если уж есть какая-то необходимость таскать по 1 байту, то от hal лучше отказаться, имхо. второе решение выглядит элегантнее.
Go to the top of the page
 
+Quote Post
Reanimator++
сообщение Apr 28 2011, 05:43
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 399
Регистрация: 1-01-06
Из: Волгоград
Пользователь №: 12 763



Нет, это не решение а синтетический тест )
Я написал программу на 20 тыщ строк которая крутится в суперцикле и одним из ее действий является чтение данных из UART.
Получается если я хоть раз вызываю read до того как ответ получен, то есть вероятность потери байтов. Т.е. фактически он бесполезен и UART-ом пользоваться нельзя...

зы. нашел драйвер, просмотрел код, запрещения прерываний при чтении не обнаружил.. как он вообще работает? (там есть действия связанные с семафорами, вот они расставлены грамотно, но я так понимаю что это будет работать только если я микриум задействую..)
Go to the top of the page
 
+Quote Post
vadimuzzz
сообщение Apr 28 2011, 07:20
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 291
Регистрация: 21-07-05
Пользователь №: 6 988



Цитата(Reanimator++ @ Apr 28 2011, 12:43) *
Получается если я хоть раз вызываю read до того как ответ получен, то есть вероятность потери байтов.

можно использовать блокирующее чтение. либо DMA
Go to the top of the page
 
+Quote Post
Reanimator++
сообщение Apr 28 2011, 08:05
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 399
Регистрация: 1-01-06
Из: Волгоград
Пользователь №: 12 763



Блокирующее не вариант, не дай бог байтик не дошел и все, девайс завис. Ладно бы был вариант чтения с таймаутом.. Да все-равно, UART-ов несколько, обслуживать все надо.
В общем я расстроен, так надеялся что не надо будет драйвер делать самому, думаю - как здорово, альтера уже написала все...

Попробую переписать на свой.

А DMA это интересно, там конфликт чтение/запись разруливается на уровне шины? И ограничений на количество DMA нету?
Go to the top of the page
 
+Quote Post
vadimuzzz
сообщение Apr 28 2011, 08:11
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 291
Регистрация: 21-07-05
Пользователь №: 6 988



Цитата(Reanimator++ @ Apr 28 2011, 15:05) *
А DMA это интересно, там конфликт чтение/запись разруливается на уровне шины? И ограничений на количество DMA нету?

главное там - прерывание по приему всего пакета. ограничений на кол-во каналов нет.
Go to the top of the page
 
+Quote Post
Reanimator++
сообщение Apr 28 2011, 10:47
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 399
Регистрация: 1-01-06
Из: Волгоград
Пользователь №: 12 763



Упростил драйвер UART-а до четырех строчек, запретил прерывания во время чтения, не помогло.

Опытным путем выяснил что проблема связана с JTAG UART. Когда отключаешь Nios II JTAG UART Console, а потом снова включаешь то приходят данные в количестве размера буфера JTAG UART из printf ("%ld\n", recieved); с верным числом байт в пакете. А потом снова начинаются потери. Видимо там есть что-то надолго блокирующее прерывания, буду читать дальше код..
Go to the top of the page
 
+Quote Post
iosifk
сообщение Apr 28 2011, 10:52
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(Reanimator++ @ Apr 28 2011, 14:47) *
Опытным путем выяснил что проблема связана с JTAG UART.


Так может просто в JTAG происходит сбой? Там все импульсы проверены? Может скорость обмена по этому порту понизить?


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
Reanimator++
сообщение Apr 28 2011, 11:02
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 399
Регистрация: 1-01-06
Из: Волгоград
Пользователь №: 12 763



Дык сбой там или нет, зачем же прерывания-то тормозить? Наполнил буфер и сиди жди пока интерфейс отпустит ) Как-то не по-русски сделано.
Попробую пересобрать систему без использования JTAG UART и распаяю еще один RS-232, перенаправив на него stdout..
Go to the top of the page
 
+Quote Post
Reanimator++
сообщение Apr 28 2011, 14:26
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 399
Регистрация: 1-01-06
Из: Волгоград
Пользователь №: 12 763



Попробовал с железным RS-232 - все работает нормально. В общем JTAG UART - пользоваться осторожно...
Go to the top of the page
 
+Quote Post
Reanimator++
сообщение Apr 28 2011, 16:00
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 399
Регистрация: 1-01-06
Из: Волгоград
Пользователь №: 12 763



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

А как бы вы оценивали сколько процентов времени процессор проводит в прерывании?
зы. теперь понимаю почему гугль так часто выдавал мне темы про Fifo-ed UART..
Go to the top of the page
 
+Quote Post
Stewart Little
сообщение Apr 28 2011, 16:06
Сообщение #12


Лентяй
******

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



Цитата(Reanimator++ @ Apr 28 2011, 20:00) *
... программа исполняется из SDRAM, процессор средний - NiosII/e, частота 54 МГц. Не думал что это будет настолько медленно...

NiosII/e - это минимальная конфигурация (Economy), это действительно тормоз, особенно с прерываниями (кстати, для саморазвития почитайте, как там организована обработка прерываний wacko.gif ).
Средняя конфигурация называется Standard, и, соответственно, /s.
А если используете Fast, то имеет смысл добавить VIC - тогда с прерываниями вообще хорошо станет.


--------------------
Чтобы слова не расходились с делом, нужно молчать и ничего не делать...
Go to the top of the page
 
+Quote Post
Reanimator++
сообщение Apr 28 2011, 16:14
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 399
Регистрация: 1-01-06
Из: Волгоград
Пользователь №: 12 763



Пардон, ошибся, это был Standard - /s.
А про VIC где прочитать что это, в Nios II Processor Reference Handbook и в Nios II Software Developer's Handbook что-то не разглядел..
Go to the top of the page
 
+Quote Post
Stewart Little
сообщение Apr 28 2011, 16:23
Сообщение #14


Лентяй
******

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



Цитата(Reanimator++ @ Apr 28 2011, 20:14) *
Пардон, ошибся, это был Standard - /s.
А про VIC где прочитать что это, в Nios II Processor Reference Handbook и в Nios II Software Developer's Handbook что-то не разглядел..

Vectored Interrupt Controller
Примеры


--------------------
Чтобы слова не расходились с делом, нужно молчать и ничего не делать...
Go to the top of the page
 
+Quote Post
Reanimator++
сообщение Apr 28 2011, 16:49
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 399
Регистрация: 1-01-06
Из: Волгоград
Пользователь №: 12 763



Спасибо за поддержку!
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st June 2025 - 23:57
Рейтинг@Mail.ru


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