Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F2xx USB FS CDC
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
BaN
Пытаюсь разобраться с работой USB full-speed в STM32 на примере USB CDC от ST из STM32_USB-Host-Device_Lib_V2.1.0. Хочу добиться скорости 800кБ/с передачи в одну сторону от устройства до ПК.
Использую драйвер VCP_V1.3.1 от ST.
Работаю с STM32F205RBT6.
Прием/передача нормально работают, но хочется выжать максимальную пропускную способность в одном направлении (от устройства к ПК).
И здесь возникли трудности, не удается получить более 740кБ/с (чуть меньше половины от максимальной пропускной способности USB FS).
В пример внес изменения:
Код
#define CDC_IN_FRAME_INTERVAL          0    /* Number of frames between IN transfers */
#define APP_RX_DATA_SIZE               32768 /* Total size of IN buffer: */

В основном цикле отправляю данные со скоростью 1МБ/с:
Код
  uint32_t cnt = 0;
  uint32_t value = 4;
  while (1)
  {
      // Запуск отсчета задержки value мс
      TIM2->PSC = (2*30000000/1000)/((value == 1) ? 2 : 1)-1;    //настроить делитель для формирования милисекунд
      TIM2->ARR = (value == 1) ? 1 : (value-1);                  //загрузить значение задержки
      TIM2->CNT = 0;
      TIM2->EGR = TIM_EGR_UG;
      TIM2->SR &= ~TIM_SR_UIF;
      TIM2->CR1 = TIM_CR1_OPM | TIM_CR1_CEN;        //запустить таймер

      for (uint32_t j = 0; j < 1024; j++)
      {
          APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[3];
          APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[2];
          APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[1];
          APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[0];
          cnt++;
      }
      if(APP_Rx_ptr_in == APP_RX_DATA_SIZE)
      {
        APP_Rx_ptr_in = 0;
      }

      while((TIM2->SR & TIM_SR_UIF)==0){} //дождаться конца задержки
      TIM2->SR &= ~TIM_SR_UIF;        //сбросить флаг
    }

Здесь идет запись в буфер раз в 4мс по 4096б, при этом достигается скорость 740кБ/с. Если записывать в буфер раз в 2мс по 2048б, при этом достигается скорость 660кБ/с. При записи в буфер меньшими объемами, но чаще, например каждую 1мс по 1024б (0,5мс/512б, 0,25мс/256б), уже скорость падает до 500кБ/с. Я так понимаю, что это из-за NACK.
Но что ограничивает максимальную пропускную способность при передаче в одну сторону до половины от максимально возможной?
Дело в драйвере VCP от ST на ПК или я что-то не учитываю на стороне устройства?
vptr
Цитата(BaN @ Apr 28 2013, 11:01) *
Пытаюсь разобраться с работой USB full-speed в STM32 на примере USB CDC от ST из STM32_USB-Host-Device_Lib_V2.1.0. Хочу добиться скорости 800кБ/с передачи в одну сторону от устройства до ПК.
Использую драйвер VCP_V1.3.1 от ST.
Работаю с STM32F205RBT6.
Прием/передача нормально работают, но хочется выжать максимальную пропускную способность в одном направлении (от устройства к ПК).
И здесь возникли трудности, не удается получить более 740кБ/с (чуть меньше половины от максимальной пропускной способности USB FS).
В пример внес изменения:
Код
#define CDC_IN_FRAME_INTERVAL          0    /* Number of frames between IN transfers */
#define APP_RX_DATA_SIZE               32768 /* Total size of IN buffer: */

В основном цикле отправляю данные со скоростью 1МБ/с...

А разве не эта запись
Код
#define CDC_DATA_MAX_PACKET_SIZE       64   /* 64 Endpoint IN & OUT Packet size */
ограничивает число байт, отправляемых за 1 мс по приходу SOF. Тогда получается максимальная скорость 1000*64 = 64 000 Байт = 64000*8=512 000 бит/сек
BaN
Цитата(vptr @ Apr 28 2013, 16:28) *
А разве не эта запись
Код
#define CDC_DATA_MAX_PACKET_SIZE       64   /* 64 Endpoint IN & OUT Packet size */
ограничивает число байт, отправляемых за 1 мс по приходу SOF. Тогда получается максимальная скорость 1000*64 = 64 000 Байт = 64000*8=512 000 бит/сек

Я так понял, что это максимальный размер bulk-пакета, который для full-speed составляет 64 байт или это не то? Попробую поизменять.
Да, это именно максимальный размер bulk-пакета, так что больше 64 байт никак.
Если я не ошибаюсь, за один SOF может выполняться несколько транзакций из одной конечной точки.
vptr
Цитата(BaN @ Apr 28 2013, 12:34) *
Если я не ошибаюсь, за один SOF может выполняться несколько транзакций из одной конечной точки.

Транзакций несколько, но вот остается вопрос, стек от STM выполняет ли это? И сколько максимальное число транакций, после одного SOF?
BaN
Цитата(vptr @ Apr 28 2013, 18:10) *
Транзакций несколько, но вот остается вопрос, стек от STM выполняет ли это? И сколько максимальное число транакций, после одного SOF?

Судя по тому, что мне удается достичь скоростей больших, чем 64кБ/с, то выполняет. Неизвестно, ограничивает ли именно драйвер число транзакций, но сам USB-хост, судя по гуглу, ограничивает число транзакций так:
Цитата
В каждом кадре может быть выполнено несколько транзакций, их допустимое число зависит от скорости, длины поля данных каждой из них, а также от задержек, вносимых кабелями, хабами и устройствами.

Проверял работу устройства, когда оно было подключено к корневому хабу напрямую и только одно, так что ничто из этого не должно было мешать.
Еще появилась мысль, а после каждого ли SOF ПК принимает данные из устройства, попробую проверить это.
vptr
Цитата(BaN @ Apr 28 2013, 14:23) *
Судя по тому, что мне удается достичь скоростей больших, чем 64кБ/с, то выполняет. Неизвестно, ограничивает ли именно драйвер число транзакций, но сам USB-хост, судя по гуглу, ограничивает число транзакций так:

Скорость со стороны ПК чем контролируется? Это самописное ПО или чего-то стандартное?
BaN
Цитата(vptr @ Apr 28 2013, 18:28) *
Скорость со стороны ПК чем контролируется? Это самописное ПО или чего-то стандартное?

Сделал программку для проверки пропускной способности в mingw.
Принимаю информацию из COM-порта и записываю в файл.
CODE
int RS232_PollComport(int comport_number, unsigned char *buf, int size)
{
int n;

if(size>4096) size = 4096;

/* added the void pointer cast, otherwise gcc will complain about */
/* "warning: dereferencing type-punned pointer will break strict aliasing rules" */

ReadFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL);

return(n);
}

Цикл в main:

while(1)
{
n = RS232_PollComport(cport_nr, buf, 4095);
if (n != 0)
{
fwrite (buf , 1 , n , file );
}
}
Завершение программы по Ctrl+C:
BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
{
if (fdwCtrlType == CTRL_C_EVENT)
{
fclose(file);
exit(1);
}
return FALSE;
}

Включаю программу и засекаю секундомером промежуток времени, секунд 20, потом закрываю программу и вычисляю скорость размер_файла/20_секунд.
BaN
Проверил как идет передача. После каждого SOF передается от 3 до 16 транзакций (большинство по 14).
Я правильно понимаю суть, что USB FS позволяет одной конечной точке за 1 кадр передавать максимум 1 пакет данных размером до 1023 байта (т.е. до 16 транзакций за 1 кадр)? И тогда предельная пропускная способность USB FS при идеальных условиях 1МБ/с?
vptr
Цитата(BaN @ Apr 28 2013, 18:24) *
Проверил как идет передача. После каждого SOF передается от 3 до 16 транзакций (большинство по 14).
Я правильно понимаю суть, что USB FS позволяет одной конечной точке за 1 кадр передавать максимум 1 пакет данных размером до 1023 байта (т.е. до 16 транзакций за 1 кадр)? И тогда предельная пропускная способность USB FS при идеальных условиях 1МБ/с?

вот ветка http://electronix.ru/forum/index.php?showt...p;#entry1121225,
пишут что 19 транзакций за 1 кадр. Вопрос в том, чтобы все это на компьютере собрать и не потерять.
BaN
Цитата(vptr @ Apr 28 2013, 23:42) *
вот ветка http://electronix.ru/forum/index.php?showt...p;#entry1121225,
пишут что 19 транзакций за 1 кадр. Вопрос в том, чтобы все это на компьютере собрать и не потерять.

Да, меня ввело в заблуждение написанное в даташите на USB 2.0 в разделе 8.4.4 Data Packets:
The maximum data payload size allowed for low-speed devices is 8 bytes. The maximum data payload size for full-speed devices is 1023. The maximum data payload size for high-speed devices is 1024 bytes.
Это относилось к изохронным передачам.
Попробую покопать в сторону уменьшения времени ответа на запрос данных от хоста, возможно проблема лежит в этом.
toweroff
Я пробовал, правда на lpc2478, раскочегарить FS
Больше 980 КБ/сек не получилось. Никакие классы не реализовывались, данные гонялись чисто булками под libusb
BaN
Возможно, проблема в организации буфера в примере:
При получении SOF вычисляется длина данных, которые нужно отправить APP_Rx_length:
CODE
if (APP_Rx_ptr_out == APP_RX_DATA_SIZE)
{
APP_Rx_ptr_out = 0;
}

if(APP_Rx_ptr_out == APP_Rx_ptr_in)
{
USB_Tx_State = 0;
return;
}

if(APP_Rx_ptr_out > APP_Rx_ptr_in) /* rollback */
{
APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out;

}
else
{
APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out;

}

APP_Rx_ptr_out - указатель на место, с которого начинать читать данные из буфера для отправки на ПК
APP_Rx_ptr_in - последние сохраненные данные в буфере
Я почему-то думал, что там должен быть кольцевой буфер, но там обычный буфер и в случае, если APP_Rx_ptr_out > APP_Rx_ptr_in, на отправку поступает только конец буфера, а уже записанные данные в начале буфера в данном кадре не передаются, а передадутся только уже в следующем. И тогда, если от APP_Rx_ptr_out до конца буфера будет мало данных, то и максимальная пропускная способность уменьшится.
Может проблема была где-то в этом. Хотя, исходя из того, что у меня буфер 32кБ и за кадр, допустим, передается по ~1кБ, то в случае описаном выше, была бы потеря в скорости не более 1/32, т.е. итоговая скорость была бы где-нибудь 970кБ/с.
UPD:
И еще, похоже где-то тормоза кроются в прерывании, т.к. если просто в цикле мэйна забивать данные в буфер без задержек на максимальной скорости, данные в буфере не перекрываются и на ПК принимается все последовательно. Для проверки записывал в цикле в буфер переменную uint32_t cnt с инкрементом.
Код
  uint32_t cnt = 0;
  while (1)
  {
      APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[3];
      APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[2];
      APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[1];
      APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[0];
      cnt++;
      if(APP_Rx_ptr_in == APP_RX_DATA_SIZE)
      {
        APP_Rx_ptr_in = 0;
      }
  }

UPD2:
Измерил, 5мкс МК проводит в прерывании USB, 600нс проводит вне прерывания. Буду копать дальше.
UPD3:
У меня, похоже, какие-то проблемы с тактовой частотой.
Вывожу на пин частоту:
Код
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
while(1)
{
    GPIOB->BSRRL = GPIO_Pin_12;
    GPIOB->BSRRH = GPIO_Pin_12;
}

Вижу на выходе 10МГц. Непонятно, почему тактовая частота получается 20МГц, т.к. в system_stm32f2xx.c, который я использую по-умолчанию, настройка идет на 120МГц, кварц стоит 25МГц, питание 3,3В. Проверил SetSysClock(), PLL нормально настраивается на работу от HSE. Как так получается?
UPD4:
На кварце видна синусоида 25МГц.
UPD5:
Нашел причину этой проблемы, но не понимаю, почему она возникает.
При включении оптимизации по размеру, начала выводиться на пин нормальная частота.
Выключил оптимизацию - снова появляется эта проблема.
Компилятор Sourcery CodeBench Lite 2012.09-63.
vptr
...
BaN
Проверил еще раз, с тактовой частотой всё нормально. Какие-то проблемы с изменением состояния пина.
Проверял так:
CODE
int main(void)
{
uint32_t loops_const = (uint32_t)((double)1 * 120000000 / 3000000.0);
uint32_t loops;
GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
__disable_irq();
while(1)
{
loops = loops_const;
GPIOA->BSRRL = GPIO_Pin_15;
GPIOB->BSRRL = GPIO_Pin_12;
asm volatile (
"1: SUBS %[loops], %[loops], #1 \n"
" BNE 1b \n"
: [loops] "+r"(loops)
);
GPIOB->BSRRH = GPIO_Pin_12;
GPIOA->BSRRH = GPIO_Pin_15;
GPIOA->BSRRL = GPIO_Pin_15;
GPIOA->BSRRH = GPIO_Pin_15;
GPIOA->BSRRL = GPIO_Pin_15;
GPIOA->BSRRH = GPIO_Pin_15;
loops = loops_const;
asm volatile (
"1: SUBS %[loops], %[loops], #1 \n"
" BNE 1b \n"
: [loops] "+r"(loops)
);
}
}

При включении оптимизации по размеру или по скорости, всё работает нормально, делается задержка на 1мкс между 1 и 0 вывода GPIOB.GPIO_Pin_12, после этого идут переключения с частотой 120МГц вывода GPIOA.GPIO_Pin_15.
Если отключить оптимизацию, то задержка 1мкс также формируется, но время между переключениями состояния на выводе GPIOA.GPIO_Pin_15 становится по 25нс.
Почему так происходит понять не могу.
UPD1:
Ассемблерный код генерируется нормальный:
Код
606 039c 0B4B             ldr    r3, .L48
607 039e 4FF48052         mov    r2, #4096
608 03a2 1A83             strh    r2, [r3, #24]    @ movhi
609 03a4 094B             ldr    r3, .L48
610 03a6 4FF48052         mov    r2, #4096
611 03aa 5A83             strh    r2, [r3, #26]    @ movhi
...
626                  .L48:
627 03cc 00040240         .word    1073873920

Где искать проблему?
UPD2:
Разобрался, что-то я опять затупил, без оптимизации будет 3 команды по 8нс, как раз выйдет 24нс, а с оптимизацией будет просто последовательные strh и выйдет по 8нс.
UPD3:
Вот только при включении оптимизации перестает работать передача по USB. Прием работает.
UPD4:
Исправил отключением оптимизации для цикла отправки данных для ПК, выделив это в одну функцию и добавив её атрибут __attribute__((optimize("-O0"))).
BaN
Подкорректировал буфер USB:
Код
#define RX_FIFO_FS_SIZE                           35
#define TX0_FIFO_FS_SIZE                          17
#define TX1_FIFO_FS_SIZE                         252
#define TX2_FIFO_FS_SIZE                          16
#define TX3_FIFO_FS_SIZE                           0

Внес изменения и сделал передачу как описал здесь chinzei.tsuneo:
https://my.st.com/public/STe2ecommunities/m...currentviews=96
Для проверки просто в цикле отправлял весь буфер на передачу:
Код
while (1)
{
    if ( (USB_OTG_dev.dev.device_status == USB_OTG_CONFIGURED) && (USB_Tx_State == 0 ))
    {
      USB_Tx_State = 1;
      DCD_EP_Tx (&USB_OTG_dev, CDC_IN_EP, (uint8_t*)&APP_Rx_Buffer[0], APP_RX_DATA_SIZE);
    }
}

Получил скорость:
613093375 bytes read per 634260 ms, average speed 943 kB/s
jcxz
Если CDC - не обязательное условие, то создавайте одну изохронную точку 1023байт и получите гарантированные 999кБ/сек.
Без всяких танцев с бубном....
+ можно ещё чуток дожать на параллельных control-пакетах wink.gif
BaN
Цитата(jcxz @ May 2 2013, 09:39) *
Если CDC - не обязательное условие, то создавайте одну изохронную точку 1023байт и получите гарантированные 999кБ/сек.
Без всяких танцев с бубном....
+ можно ещё чуток дожать на параллельных control-пакетах wink.gif

По ТЗ нужно именно CDC, т.к. требуется совместимость со старой версией устройства с RS-232.
BaN
Опять у меня проблемы с обменом. Нужно передавать непрерывный поток данных 750кБ/с.
При отправке данных в цикле:
Код
while (1)
{
    if ( (USB_OTG_dev.dev.device_status == USB_OTG_CONFIGURED) && (USB_Tx_State == 0 ))
    {
      USB_Tx_State = 1;
      DCD_EP_Tx (&USB_OTG_dev, CDC_IN_EP, (uint8_t*)&APP_Rx_Buffer[0], APP_RX_DATA_SIZE);
    }
}

Достигается скорость 950кБ/с.
Сделал проверочную отправку непрерывного потока данных 750кБ/с:
CODE
#define APP_RX_DATA_SIZE (7*4096)
...
uint8_t APP_Rx_Buffer [APP_RX_DATA_SIZE];
uint8_t APP_Rx_Buffer_2 [APP_RX_DATA_SIZE];
...
SysTick_Config(SystemCoreClock /48000);
while (1)
{
if (new_data_ready == 1)
{
static uint32_t cnt = 0;
uint8_t *buf_ptr;

new_data_ready = 0;
if (USB_Tx_Buf_State == 0)
{
buf_ptr = APP_Rx_Buffer;
}
else
{
buf_ptr = APP_Rx_Buffer_2;
}

if(APP_Rx_ptr_in == APP_RX_DATA_SIZE)
{
if (APP_Rx_ptr_in_OVERFLOW <= (APP_RX_DATA_SIZE-8))
{
buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'O';
buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'V';
buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'E';
buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'R';
buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'F';
buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'L';
buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'O';
buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'W';
}
}
else
{
// Записываем 16 байт данных с частотой 48кГц
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[3];
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[2];
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[1];
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[0];
cnt++;
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[3];
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[2];
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[1];
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[0];
cnt++;
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[3];
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[2];
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[1];
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[0];
cnt++;
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[3];
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[2];
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[1];
buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[0];
cnt++;
}
}
if ( (USB_OTG_dev.dev.device_status == USB_OTG_CONFIGURED) && (USB_Tx_State == 0 ) && (APP_Rx_ptr_in > (4096-1)))
{
uint8_t *buf_ptr;
uint8_t *fill_ptr;
uint32_t buf_leftovers;
uint32_t len;

if (USB_Tx_Buf_State == 0)
{
buf_ptr = APP_Rx_Buffer;
fill_ptr = APP_Rx_Buffer_2;
USB_Tx_Buf_State = 1;
}
else
{
buf_ptr = APP_Rx_Buffer_2;
fill_ptr = APP_Rx_Buffer;
USB_Tx_Buf_State = 0;
}
len = APP_Rx_ptr_in;
APP_Rx_ptr_in = 0;
APP_Rx_ptr_in_OVERFLOW = 0;
// Копируем данные из бефера, которые не кратны 4096
// т.к. приемный буфер драйвера VCP от ST размером 4096
buf_leftovers = len & 0x00000FFF;
len -= buf_leftovers;
while (APP_Rx_ptr_in < buf_leftovers)
{
fill_ptr[APP_Rx_ptr_in] = buf_ptr[(len+APP_Rx_ptr_in)];
APP_Rx_ptr_in++;
}

USB_Tx_State = 1;
DCD_EP_Tx (&USB_OTG_dev, CDC_IN_EP, buf_ptr, len);
}
}
...
void SysTick_Handler(void)
{
new_data_ready = 1;
}

При проверке подключаю устройство напрямую к корневому хабу, все остальные устройства отключаю от шины USB. Настраиваю USBlyzer на логгирование всех устройств на шине (моего устройства, всех хабов, всех хостов).
И в итоге всё нормально передается, но почему-то возникает нечастая (может подряд через несколько сотен мс, может через несколько десятков секунд) непериодическая задержка между передачами разной длительностью в среднем 40мс, но до 100мс, из-за которой у меня забиваются буферы и данные теряются. При этом, судя по логу, никакого трафика на шине в этот момент не идет.
Что это вообще может быть?
Golikov A.
Среда? Фоновые процессы? Например C# так может мусор собирать, фреймворк виндовый теперь тоже что-то подобное может творить... УСБ передает когда у него хост данные запросит, так что если ваш компьютер что-то делает и тупит, передача и стоит...
BaN
Цитата(Golikov A. @ May 3 2013, 12:04) *
Среда? Фоновые процессы? Например C# так может мусор собирать, фреймворк виндовый теперь тоже что-то подобное может творить... УСБ передает когда у него хост данные запросит, так что если ваш компьютер что-то делает и тупит, передача и стоит...

Windows 7 Professional SP1 32-bit.
ОЗУ 2Гб, процессор Core2Duo 2ГГц, проверял на ноутбуке Toshiba Satellite A200-1IW.
Сейчас поубивал все лишние процессы.
Код
Имя образа                     PID Имя сессии          № сеанса       Память
========================= ======== ================ =========== ============
System Idle Process              0 Services                   0        24 КБ
System                           4 Services                   0       236 КБ
smss.exe                       352 Services                   0       540 КБ
csrss.exe                      620 Services                   0     1 644 КБ
wininit.exe                    816 Services                   0       952 КБ
csrss.exe                      824 Console                    1    10 048 КБ
winlogon.exe                   880 Console                    1     2 744 КБ
services.exe                   908 Services                   0     5 660 КБ
lsass.exe                      940 Services                   0     5 852 КБ
lsm.exe                        948 Services                   0     2 716 КБ
svchost.exe                   1060 Services                   0     4 660 КБ
svchost.exe                   1136 Services                   0     4 260 КБ
Ati2evxx.exe                  1184 Services                   0     1 848 КБ
svchost.exe                   1268 Services                   0     9 248 КБ
svchost.exe                   1312 Services                   0    31 032 КБ
svchost.exe                   1336 Services                   0    15 392 КБ
svchost.exe                   1476 Services                   0     3 264 КБ
svchost.exe                   1548 Services                   0     6 180 КБ
Ati2evxx.exe                  1644 Console                    1     3 732 КБ
spoolsv.exe                   1760 Services                   0     5 296 КБ
svchost.exe                   1792 Services                   0     4 052 КБ
explorer.exe                   632 Console                    1    54 272 КБ
taskhost.exe                  1152 Console                    1     4 572 КБ
acrotray.exe                  2248 Console                    1     1 212 КБ
issch.exe                     2256 Console                    1     1 404 КБ
TPwrMain.exe                  2272 Console                    1     2 764 КБ
TCrdMain.exe                  2644 Console                    1     5 736 КБ
TosCoSrv.exe                  2760 Services                   0     1 144 КБ
KeNotify.exe                  2960 Console                    1     1 392 КБ
CeEKey.exe                    2972 Console                    1     1 536 КБ
nncron.exe                    3076 Console                    1       604 КБ
nnguard.exe                   3304 Console                    1       180 КБ
svchost.exe                   3648 Services                   0     1 536 КБ
RtHDVCpl.exe                  4044 Console                    1     2 660 КБ
lock.exe                      3352 Console                    1     3 164 КБ
cmd.exe                       5240 Console                    1     1 556 КБ
conhost.exe                   5072 Console                    1     2 132 КБ
HxD.exe                       3544 Console                    1    10 696 КБ
notepad++.exe                 5832 Console                    1    31 932 КБ
USBLyzer.exe                  2348 Console                    1   290 392 КБ
serial.exe                    1236 Console                    1     2 888 КБ
conhost.exe                   3512 Console                    1     3 888 КБ
audiodg.exe                   6120 Services                   0    15 064 КБ
TrustedInstaller.exe          4980 Services                   0     5 960 КБ
tasklist.exe                   444 Console                    1     4 588 КБ
WmiPrvSE.exe                  4412 Services                   0     5 192 КБ

Эта задержка стала появляться намного реже, но не исчезла.
Например, записал файл 770МБ, задержка была только 2 раза на 157-ом МБ, на 635 МБ.
Теперь в USBlyzer'е почему-то время в колонке Time стало обновляться раз в 15-16мс.
UPD:
Записал еще один файлик на 1,67Гб, задержки возникали 7 раз по адресам:
04AE7000
15348000
22593000
3C2F9000
4DD17000
62F16000
675F6000
Попробую на другом компьютере проверить.
jcxz
Цитата(BaN @ May 2 2013, 19:35) *
Опять у меня проблемы с обменом. Нужно передавать непрерывный поток данных 750кБ/с.
Если у вас требование по ТЗ - передача потока с фиксированной скоростью и при этом использование bulk - это явное противоречие. bulk - не предназначен для передач с гарантированной скоростью.
bulk - это фоновая передача с низшим приоритетом.
Для гарантированной полосы вам нужна изохронная передача и только она.
Правьте ТЗ.

Если так уж нужно чтоб ваше устройство выглядело на стороне PC как COM-порт, создайте виртуальный COM сторонними драйверами и передавайте потоки (RX/TX) через две изохронные точки. sm.gif
BaN
Цитата(jcxz @ May 3 2013, 16:56) *
Если у вас требование по ТЗ - передача потока с фиксированной скоростью и при этом использование bulk - это явное противоречие. bulk - не предназначен для передач с гарантированной скоростью.
bulk - это фоновая передача с низшим приоритетом.
Для гарантированной полосы вам нужна изохронная передача и только она.
Правьте ТЗ.

Если так уж нужно чтоб ваше устройство выглядело на стороне PC как COM-порт, создайте виртуальный COM сторонними драйверами и передавайте потоки (RX/TX) через две изохронные точки. sm.gif

Попробую пока сделать тестовую передачу через изохронную точку и посмотреть, будет ли возникать эта же задержка.
jcxz
Да с чего бы она возникала??? Это-бы противоречило стандарту USB.
Задержка в изохронной - это эквивалентно потере кадров.
У меня девайс с изохронной точкой ~870байт работает часами без проблем - потерь кадров ==0.
BaN
Цитата(jcxz @ May 3 2013, 22:02) *
Да с чего бы она возникала??? Это-бы противоречило стандарту USB.
Задержка в изохронной - это эквивалентно потере кадров.
У меня девайс с изохронной точкой ~870байт работает часами без проблем - потерь кадров ==0.

А с чего эта задержка возникает у меня в случае с bulk-передачами, если на шине никакого обмена нет и, согласно спецификации USB, вся шина должна была бы отдаваться bulk-передачам?
aaarrr
Цитата(BaN @ May 3 2013, 19:19) *
А с чего эта задержка возникает у меня в случае с bulk-передачами, если на шине никакого обмена нет и, согласно спецификации USB, вся шина должна была бы отдаваться bulk-передачам?

Шина не занята, занята система. А так как у шины нет неотложных дел типа изохронных передач, то её обслуживание вполне может попасть под нож.
BaN
Цитата(aaarrr @ May 3 2013, 22:53) *
Шина не занята, занята система. А так как у шины нет неотложных дел типа изохронных передач, то её обслуживание вполне может попасть под нож.

Да, вполне вероятное предположение. Здесь даже тест проводили на эту тему:
http://www.microchip.com/forums/m291283-p2.aspx
Цитата
As far as I remember I made tests about iso speed vs. cpu load, and iso speed was always correct.
Bulk speed on the contrary was apparently affected.

Но нигде конкретно не описаны приритеты ОС в таких случаях.
Пока попробую с изохронной передачей.
BaN
Еще нашел баг в библиотеке, из-за которого у меня постоянно происходили прерывания с частотой 500кГц:
https://my.st.com/public/STe2ecommunities/m...rrentviews=1112
ander0
BaN, можете выложить исходники своего последнего варианта?) Какая частота кварца у вашего устройства?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.