Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Скорость USB на AT91SAM7S
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Edmundo
Сделал проектик на базе Atmel'овского "AT91SAM7S64-BasicUSB". Там bulk-обмен с размером буфера 64 байта. Гонял обмен туда-сюда следующим образом: большой буфер делил на куски по 64 байта и WriteFile'ом (и соотв. ReadFile) прогонял. На МК ловил/отправлял с помощью AT91F_L1USB_GET_Data и AT91F_L1USB_PUT_Data, которые тоже бьют массив на части:

Код
void AT91F_L1USB_PUT_Data(char* data,unsigned int length)
{
    unsigned int size;

    while(length)
    {
        size = (length<SIZEBUFMAX) ? length : SIZEBUFMAX; // SIZEBUFMAX=64
        AT91F_L0USB_PUT_Data(data, size); //  это фактически pCDC.Write(&pCDC, data, length);
        length -= size;
        data += size;
    }
}


Чего-то скорость не очень большая. Количественных замеров не сделал еще, качественно где-то на уровне сотни килобайт в секунду, мне кажется не больше. Как-то по-быстрее хотелось бы smile.gif

В связи с чем три вопроса:
1) Можно ли как-то ускорить обмен (может, что-то по-другому делать)?
2) Этот пример на USB 1.1, как я понял (bcdUSBL=0x0110), чтобы сделать его 2.0 достаточно просто указать в bcdUSBL 0x0200?
3) Какие скорости у вас получались?
beer_warrior
Я тоже плясал от basicUSB, но поскольку задача была гонять большие объемы (единицы мегабайт), я сразу отгрыз на буфер половину ОЗУ.
Читал/писал одним Read/WriteFile с фиксированным размером приема/передачи.
Максимум что получил 4 МБ/с, что меня вполне удовлетворило, и дальнейшего повышения скорости не производил.
Настройки USB не изменял.
Так что возможно это у вас накладные расходы Винды на передаче маленьких фрагментов.
Edmundo
Цитата(beer_warrior @ May 23 2006, 13:30) *
Я тоже плясал от basicUSB, но поскольку задача была гонять большие объемы (единицы мегабайт), я сразу отгрыз на буфер половину ОЗУ.
Читал/писал одним Read/WriteFile с фиксированным размером приема/передачи.
Максимум что получил 4 МБ/с, что меня вполне удовлетворило, и дальнейшего повышения скорости не производил.
Настройки USB не изменял.
Так что возможно это у вас накладные расходы Винды на передаче маленьких фрагментов.

А можно поподробнее smile.gif
Как заставить ReadFile/WriteFile обработать весь заданный размер? Ведь они по-моему вываливаются после получения ACK и возвращают фактическое число полученных байт (64 байта по размеру endpoint'а). Что-то в sys-драйвере поменять? Или я не так понимаю суть процесса?
И как на МК получить разом 8К байт -- через AT91F_L1USB_GET_Data или как-то напрямую (чтобы избежать накладных расходов)?
beer_warrior
Не буду утверждать стопроцентно, поскольку вглубь не лазил, удовлетворился фактом работы, но
basicUSB уже предсталяет из себя CDC-устройство т.е. в файле main мы уже имеем верхний уровень
отвязаный от режимов передачи, endpoint-ов и прочей USB специфики.
У меня основной цикл выглядел так:
Код
//--------------------------------------------------------------------------
for(;;)
   {
    // Check enumeration
    if (pCDC.IsConfigured(&pCDC))
        {
        ProcessCmd();
        }
   }
}
//--------------------------------------------------------------------------
void ProcessCmd()
{
//AT91F_PIO_ForceOutput(AT91C_BASE_PIOA,~(1<<4));
pCDC.Read(&pCDC,(char*)&ask, sizeof(CMD_S));
Execute(ask.cmd);    
pCDC.Write(&pCDC,(char*)&resp, sizeof(DAT_S));
//AT91F_PIO_ForceOutput(AT91C_BASE_PIOA,(1<<4));
}
//--------------------------------------------------------------------------

где ask и resp соответственно буфера приема и передачи команды типа CMD_S - структуры в которой описан формат буферов.
Execute(ask.cmd) соответсвенно парсер команды.

Другими словами мы работаем так же как с обычным UARTом.

Со стороны хост-машины существуют исходники USBLibrary dll
Поскольку пользуюсь MInGW надо было перепиливать экспорт функций, я поленился и просто копи-пастом перенес в проект.
Суть от этого не изменилась, имеем класс CFCPipeUSB который создает два пайпа на чтение и запись.
Снаружи мы обращаемся к ним как к обычным функциям Read/Write внутри старые добрые Create-Read-Write-CloseFile т.е опять таки все хорошо известное по СОМ-портам
Отличие в том что вместо файла мы открываем пайпы и имеем не предопределенное имя порта а то что нашла энумерация USB.
Со стороны хоста получилось следующее
Код
if (pipe.Open(devname))
    {
    WxMemo->AppendText("Can't open device \n");        
    return 1;
    }
WxMemo->AppendText("Opened... \n");        
//----------------------------------
//there is exchange
//--------------------------------
WxMemo->AppendText("Write \n");        
for(int block = 0; block < 9; block ++)
    {
    if(pipe.WritePipe((char*)&ask, sizeof(CMD_S), &msgWritten))
        {
        WxMemo->AppendText("Write error 1\n");        
        pipe.Close();
        return 1;
        }
    if(sizeof(CMD_S) != msgWritten)
        {
        WxMemo->AppendText("Write error2\n" + s);        
        pipe.Close();
        return 1;
        }
    //s.Printf("%ud-%ld",sizeof(CMD_S),msgWritten);    
    //WxMemo->AppendText(s);
    if (pipe.ReadPipe ((char*)&resp, sizeof(DAT_S)))
        {
        WxMemo->AppendText("Read error\n");        
        pipe.Close();
        return 1;
        }
    }//for pipe
WxMemo->AppendText("Read\n");

Оба фрагмента уже не из теста, а реального кода, хотя возможно промежуточной версии.
Edmundo
Thanks! Вы дали мне надежду и почву для исследований smile.gif
Попишу тестовые программки, попробую разогнать (4 Мбайт/с меня бы устроило).
Shuuura
Если делать отправку в одну сторону большого объема данных, пользоваться двойной буферизацией то максимальная скорость полученая от sam7s64 1090 кбайт/с (bulk) - практический предел для usb 1.0. Ставить usb 1.1 не рекомендую, т.к. не будет работать на старых ноутбуках, да и разницы по скорости нет.
Shuuura
Вдогонку.
Если не пользоваться двойной буферизацией, то скорость падает раза в два. Обязательно надо использовать прерывания.
Harbour
Проясните - девайс реально usb 2.0 high speed режим обмена держит ? А то у них на сайте раньше было написано что только usb 1.1, теперь висит обкоцанное лого "usb certified" (сверху должна быть красная надпись high speed), маркетологи хреновы ....
Shuuura
Цитата(Harbour @ May 24 2006, 09:49) *
Проясните - девайс реально usb 2.0 high speed режим обмена держит ? А то у них на сайте раньше было написано что только usb 1.1, теперь висит обкоцанное лого "usb certified" (сверху должна быть красная надпись high speed), маркетологи хреновы ....

Для sam7s возможно ТОЛЬКО full speed (12 Мбит/с). но 12 Мбит/с это вместе со служебной информацией. Реально больше 1 мегабайта не получится. USB 2.0 и USB 1.1 в данном случае происки маркетологов в погоне за более красивой цифрой. Как и говорил ставьте 1.0 и все будет OK. biggrin.gif
KolyanV
Цитата(Edmundo @ May 23 2006, 21:52) *
Thanks! Вы дали мне надежду и почву для исследований smile.gif
Попишу тестовые программки, попробую разогнать (4 Мбайт/с меня бы устроило).

Это, наверно, опечатка, - 4 Мбит/сек, всего 500 кб/сек ...
Harbour
То-то и оно или если короче то отож ...
Edmundo
То, что реально только 1.1 -- это полнейшая засада. На сайте-то пишут "features ... a USB 2.0 device". Негодяи...
Stanislav
Цитата(Edmundo @ May 24 2006, 22:45) *
То, что реально только 1.1 -- это полнейшая засада. На сайте-то пишут "features ... a USB 2.0 device". Негодяи...
Вообще-то USB 2.0 интерфейс может работать как в High-Speed, так и Full-Speed режимах. А USB 2.0 устройство вовсе не обязано поддерживать High-Speed, на это в стандарте прямо указано.
Harbour
Вы ошиблись - usb2.0 обязано поддерживать предыдущий режим, т.е. full-speed, но чтобы получить статус usb2.0 certified, данный девайс должон уметь работать в high-speed. Здесь мы имеем просто некрасивую политику фирмы атмел - заложив год назад в чип только usb1.1 они сами себе отрезали гугошары, теперь надо как-то впихнуть народу эту ботву. С другой стороны шоб реально потянуть поток usb2.0 (480Mbit) тут надоть чип по человечески делать, т.е. даже если б у них контроллер тянул high-speed, особого толку от этого в данном кристалле нет. Тем не менее слухи проистекающие от атмеля говорят о том что будет нам счастье, со временем ...
misyachniy
usb2.0 certified - определяет как раз соответствие спецификациям стандарта для разных скоростей.
LOW/FULL/HIGH.
Для каждой скорости есть свои требования по токам потребления, полного сопротивления, точности поддержания частоты передачи и д.р.
Устройство с поддержкой любой скорости может получить сертификат.
В стандарте 2.0 добавлены "протокольные" изменения.
Например окончание передачи пакетом кратным длине Endpoint в 1.1 не предусмотрено, нeужно передавать пакет нулевой длины.
В 2.0 можно при передаче последнего паета "приклеить" информацию о том что данных больше нет, и хост обратится к другому устройству на шине.
Также можно при приеме пакета отвечать не ACK а "буферы заполнены".
При этом хост может производить обмен с другими устройствами.
В 1.1 Host передает данные до получения NACK и пакет(времяпотраченное на передачу) теряется.
Есть также дополнительные запросы которые могут завести устройства 1.1 в ступор или выдать ответ
который Host не поймет.

То есть на цифру смотреть не нужно, LOW/FULL/HIGH - вот что главное.
Harbour
Да, действительно - даже на www.usb.org есть для этих целей праздничный наббор логотипов wink.gif Sorry for noise.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.