Jump to content

    

Вопрос про CY7C68013 EZ-USB FX2

Устройство сделано так, что я отправляю туда один запрос размером 1 байт. Оно в ответ выплевывает 8 транзакций по 512 байт и одну с sync packet'ом. Потом все повторяется заново. Так вот, эта операция должна занимать не больше 1 миллисекунды. А получается какая-то ерунда. Используя USB monitor, получаю удивительные результаты. Все работает сверхбыстро, пока куда-то не пропадают 15мс(смотри скриншот). Где искать причину?

 

Значит получение 4К данных по запросу - это хреново. Чтобы достичь приличной скорости по хорошему нужно выносить всю обработку в драйвер. А так попробуй поднять приоритет процесса до реал-тайм и кидать сразу несколько запросов (точное число проверяется экспериментально) в 1 байт асинхронно приему.

 

PS: Про 15мс тебе уже ответили.

PS2: Какой скорости приема нужно достичь?

Share this post


Link to post
Share on other sites

Хорошо. Почему тогда этот другой процесс ВСЕГДА занимает 15мс? Приоритет процесса - реального времени. Запускается на втором ядре. Я могу как-то запустить его не в user mode, а в режиме ядра?

 

PS2: Какой скорости приема нужно достичь?

 

1000 таких запросов должно обрабатываться за секунду. Точнее, примерно 4МБ в секунду. Вроде, цифра детская

 

Ситуация странная. На каждую 1мс моих взаимодействий с прибором приходится 15мс потерянного времени. При том, что все остальные программы отключены и загрузка ЦП под 0%. Даже теоретическая максимальная скорость в этом случае всего 30Мбит в секунду.

 

P.S. Это если верить USB Monitor.

Edited by niktagor

Share this post


Link to post
Share on other sites
Хорошо. Почему тогда этот другой процесс ВСЕГДА занимает 15мс? Приоритет процесса - реального времени. Запускается на втором ядре. Я могу как-то запустить его не в user mode, а в режиме ядра?

1000 таких запросов должно обрабатываться за секунду. Точнее, примерно 4МБ в секунду. Вроде, цифра детская

 

15 мс - так организован системный таймер виндов. Все претензии к одному богатому пенсионеру. В режиме ядра запустить виндовое приложение - хм... А вот написать службу, которая будет рулить потоком данных - это нормальный выход.

 

Share this post


Link to post
Share on other sites
... и кидать сразу несколько запросов (точное число проверяется экспериментально) в 1 байт асинхронно приему.

Это поможет если firmware FX2LP умеет накапливать число запросов. Если нет, то есть, на каждый запрос выдается ответ в 4К, то это не поможет. А если firmware работает неправильно, то есть, по каждому запросу пытается выдать новые 512 байт не разбираясь, выданы ли предыдущие 4К, то это только усугубит ситуацию.

Share this post


Link to post
Share on other sites

Про 15 миллисекунд разобрался. Это точность системного таймера в большинстве современных компьютеров. Например Sleep(1) и Sleep(8) обе вызывают задержку на 15 миллисекунд. Так что USB Monitor с большим разрешением время посчитать не сможет. И реальные тайминги я через нее не узнаю. Вопрос: можно ли их вообще узнать, не заглядывая в USB провод приборами?

Share this post


Link to post
Share on other sites

В FX2LP есть аппаратная буферизация - как минимум 2 запроса должны пройти. Как отреагирует фирмварь это другой вопрос.

Определение временных интервалов с помощью high-resolution performance counter:

#define GETFIRSTTICK()    LARGE_INTEGER qwTickCountA[2];    \
                        QueryPerformanceCounter(&(qwTickCountA[0]));

#define GETSECONDTICKMESSAGE()    { QueryPerformanceCounter(&(qwTickCountA[1]));    \
                                LARGE_INTEGER qwFrequencyA;    \
                                QueryPerformanceFrequency(&qwFrequencyA);    \
                                double dbTMPA = (double)(qwTickCountA[1].QuadPart - qwTickCountA[0].QuadPart)/(double)qwFrequencyA.QuadPart; \
                                char szMessageA[80];    \
                                sprintf(szMessageA,"Операция завершена за %.9f секунд", dbTMPA);    \
                                ::MessageBox(0, szMessageA, ("Время работы"), MB_OK | MB_ICONINFORMATION);}

Share this post


Link to post
Share on other sites
Ситуация странная. На каждую 1мс моих взаимодействий с прибором приходится 15мс потерянного времени.

 

Про 15 миллисекунд разобрался. Это точность системного таймера в большинстве современных компьютеров. Например Sleep(1) и Sleep(8) обе вызывают задержку на 15 миллисекунд. Так что USB Monitor с большим разрешением время посчитать не сможет. И реальные тайминги я через нее не узнаю. Вопрос: можно ли их вообще узнать, не заглядывая в USB провод приборами?

Если USB Monitor серьезная программа, то для измерения промежутков времени будет использовать High-Resolution Timer (класс Stopwatch в .NET Framework). Скорее всего, в программе, которую Вы используете в цикле обмена по USB вызывается Sleep(1), что приводит к засыпанию потока Вашей программы, в котором выполняется обмен по USB на 15 миллисекунд.

Edited by Konst_777

Share this post


Link to post
Share on other sites
Про 15 миллисекунд разобрался. Это точность системного таймера в большинстве современных компьютеров. Например Sleep(1) и Sleep(8) обе вызывают задержку на 15 миллисекунд. Так что USB Monitor с большим разрешением время посчитать не сможет. И реальные тайминги я через нее не узнаю. Вопрос: можно ли их вообще узнать, не заглядывая в USB провод приборами?

Попробуйте параллельно запустить Windows Media Player в режиме воспроизведения видео или музыки -

- он повышает точность системного таймера до 1мс.

 

и все измерители времени и Sleep'ы будут работать точнее в 15 раз.

Share this post


Link to post
Share on other sites
... А получается какая-то ерунда. Используя USB monitor, получаю удивительные результаты. Все работает сверхбыстро, пока куда-то не пропадают 15мс(смотри скриншот). Где искать причину?

Про 15 миллисекунд разобрался. ... Так что USB Monitor с большим разрешением время посчитать не сможет. И реальные тайминги я через нее не узнаю...

Эх, не посмотрел я скриншот и начал фантазировать. Да, Вы правы. USB Monitor не использует High-Resolution Timer. И реальные тайминги Вы с помощью этой программы не узнаете.

Share this post


Link to post
Share on other sites

Прикрутил high-resolution timer. Выясняется, что между получаемыми пакетами задержка всегда ровно 250мкс. Это при том, что это все часть одной большой информации, и она выдается по одному запросу на 9 пакетов. Косяк явно не в приборе. Так как даже с родной программой и он выдает это быстрее. Использую метод XferData(). Посылка наперед нескольких запросов ситуацию не меняет. Завтра попробую использовать Begin\Wait\Finish DataXfer(). Есть смысл? В чем их принципиальное различие?

Share this post


Link to post
Share on other sites
Прикрутил high-resolution timer. Выясняется, что между получаемыми пакетами задержка всегда ровно 250мкс. Это при том, что это все часть одной большой информации, и она выдается по одному запросу на 9 пакетов. Косяк явно не в приборе. Так как даже с родной программой и он выдает это быстрее. Использую метод XferData(). Посылка наперед нескольких запросов ситуацию не меняет. Завтра попробую использовать Begin\Wait\Finish DataXfer(). Есть смысл? В чем их принципиальное различие?

первый метод синхронный, второй асинхронный.

Асинхронный метод позволяет посылать следующий запрос на чтение данных драйверу не дожидаясь исполнения предыдущего и таким образом можно организовать очередь запросов на чтение и получить скорость до 40-50МБайт/c.

 

Но проблема в том, то у вас нужно посылать ещё и запрос устройству для того чтобы оно выдало данные -

вот тут главные тормоза, так как Маздай от билла гейтса не является ОС реального времени и быстро переключать потоки и задачи не умеет.

 

 

 

 

Share this post


Link to post
Share on other sites
Устройство сделано так, что я отправляю туда один запрос размером 1 байт. Оно в ответ выплевывает 8 транзакций по 512 байт и одну с sync packet'ом. Потом все повторяется заново. Так вот, эта операция должна занимать не больше 1 миллисекунды. А получается какая-то ерунда. Используя USB monitor, получаю удивительные результаты. Все работает сверхбыстро, пока куда-то не пропадают 15мс(смотри скриншот). Где искать причину?
Вы НИКОГДА не получите 1мс на USB при запросе туда-обратно. Время на переключение направления Вы не уменьшите. Пробуйте посылать запросы не по одному байту, а пачками, маскимум - размер входного буфера на данном EndPoint. А потом вычитывать данные. Если устройство сделано нормально, то должно работать.

Share this post


Link to post
Share on other sites

По поводу моих 250мкс по Вашей ссылке нашел интересное сообщеньице

У шины время кадра на полной скорости 1 мС, а на высокой микрокадр - 0.125 мс. В течении этого времени в самом худшем случае ( это тот случай, если имеется простейший планировщик пакетов - один запрос в кадре) мы буим иметь задержки 2 мСек и 0.25 мСек соответственно.

В связи с этим, вопрос. Планировщик пакетов - это в cyusb.sys, или на более низком уровне?

 

Еще появилась идея перейти под linux и написать код для библиотеки libusb. На сайте написано, что вышла ее версия под Windows. Кто-нибудь пробовал? Есть ли смысл в моей ситуации?

Share this post


Link to post
Share on other sites
НИКОГДА не говорите НИКОГДА

 

PS. Обсуждалось здесь http://electronix.ru/forum/index.php?showt...=37919&st=0

Что Вы эти хотели сказать? Что время сколь угодно близко к 1мс, но все равно больше? И кто тут прав?? :) Вот Ваше мнение.

И насколько мне известно, в USB2.0 микрофреймы не могут быть туда-обратно. Только фреймы так умеют. Потому мы в реалии и видим всегда, что в лучшем случае пара мс.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this