¿Por qué el búfer recibido a través de USB no está alineado con la longitud del búfer transmitido?

0

Transmito algunos datos desde STM32H7 USB (VCP) - > a la PC, y una vez finalizada la transmisión, simplemente envío "end \ 0". Y en el lado de la PC, solo miro el inicio del bloque de datos recibidos y si hay "end \ 0", simplemente finalizo el programa de PC.

Este es el código STM32H7:

#define DMA_BUFFER_SIZE   2048
#define SIZE 2048

unsigned short int buffer[DMA_BUFFER_SIZE] __attribute__((section(".fast_buffer")));

// "end
#define NUMBER_OF_DATA_UNITS 2048
unsigned short int lpBuffer[NUMBER_OF_DATA_UNITS] = {0};
unsigned long nNumberOfBytesToRead = NUMBER_OF_DATA_UNITS*2;
unsigned long lpNumberOfBytesRead;
for(;;) {

  QueryPerformanceCounter(&startCounter);  
  ReadFile(
    hSerial,
    lpBuffer,
    nNumberOfBytesToRead,
    &lpNumberOfBytesRead,
    NULL
    );

  if(!strcmp((char *)lpBuffer, "end")) {
    CloseHandle(FileHandle);
    // we are finished
    break;
  }
  else if(lpNumberOfBytesRead > 0) {
    //write received data to the disk
  }
}// for(;;)
" buffer[0] = 0x6E65; buffer[1] = 0x0064; buffer[2] = 0x0; CDC_Transmit_HS(buffer, SIZE*sizeof(unsigned short int)); GPIOH->ODR ^= (0x1 << 2); while(((USBD_CDC_HandleTypeDef*)(hUsbDeviceHS.pClassData))->TxState != 0);

lado de la PC:

#define DMA_BUFFER_SIZE   2048
#define SIZE 2048

unsigned short int buffer[DMA_BUFFER_SIZE] __attribute__((section(".fast_buffer")));

// "end
#define NUMBER_OF_DATA_UNITS 2048
unsigned short int lpBuffer[NUMBER_OF_DATA_UNITS] = {0};
unsigned long nNumberOfBytesToRead = NUMBER_OF_DATA_UNITS*2;
unsigned long lpNumberOfBytesRead;
for(;;) {

  QueryPerformanceCounter(&startCounter);  
  ReadFile(
    hSerial,
    lpBuffer,
    nNumberOfBytesToRead,
    &lpNumberOfBytesRead,
    NULL
    );

  if(!strcmp((char *)lpBuffer, "end")) {
    CloseHandle(FileHandle);
    // we are finished
    break;
  }
  else if(lpNumberOfBytesRead > 0) {
    //write received data to the disk
  }
}// for(;;)
" buffer[0] = 0x6E65; buffer[1] = 0x0064; buffer[2] = 0x0; CDC_Transmit_HS(buffer, SIZE*sizeof(unsigned short int)); GPIOH->ODR ^= (0x1 << 2); while(((USBD_CDC_HandleTypeDef*)(hUsbDeviceHS.pClassData))->TxState != 0);

A veces, el último búfer de datos que obtengo no comienza con mi cadena "end \ 0", sino con otros datos y mi cadena "end \ 0" está en algún lugar en medio del último búfer, por lo que no puedo terminar mi rutina correctamente ¿Por qué sucede esto?

Transfiero 2048 * 2 bytes en un lote desde STM32 y recibo 2048 * 2 bytes en el lado de la PC.

¿Tal vez alguien podría darme una patada en la dirección correcta sobre cómo hacer las cosas así?

Editar:

Creo que puedo escanear cada bloque, pero esto parece algo innecesario, y la esencia de la pregunta será la misma. ¿Por qué a veces mis buffers recibidos no están alineados en 2048 * 2 bytes de longitud?

    
pregunta stronk_kisik

2 respuestas

1

Use algo como esto en el lado de la PC:

if(!strcmp((char *)lpBuffer[lpNumberOfBytesRead - 3], "end")) {
.... 
}

y algo como esto en el lado STM32:

char *endstring = "end";
CDC_Transmit_HS(endstring, strlen(endstring) + 1); // <-- I do not certain about how is this thing work so maybe just strlen
GPIOH->ODR ^= (0x1 << 2);
while(((USBD_CDC_HandleTypeDef*)(hUsbDeviceHS.pClassData))->TxState != 0);

truco simple, solo envías un paquete de 4 bytes al final de la secuencia, y solo verificas los últimos 4 bytes en el extremo receptor (lado de la PC), por lo que no es necesario ningún tipo de contador o etc. 4 bytes de cada paquete que recibe de STM32, sin importar el tamaño del paquete que obtenga.

    
respondido por el Caliban
1

Fundamentalmente, una conexión USB es solo un flujo de bytes. No hay garantía de que un búfer usado en un extremo corresponda a un búfer usado en el otro extremo. Sus datos deben formatearse para vivir dentro de esta restricción, con algún protocolo in-band inequívoco para indicar los límites del mensaje.

Además, debe asegurarse de verificar el valor de lpNumberOfBytesRead ANTES de intentar hacer algo con los datos, incluida la búsqueda de indicadores de límite. Podría estar entre 0 y nNumberOfBytesToRead .

    
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas