TIM2 100Hz in CDC_Transmit_FS

Vse kar je v povezavi z ARM-Cotrex-M procesorji. Sem spada tako HW kot SW.

Moderator: tilz0R

TIM2 100Hz in CDC_Transmit_FS

OdgovorNapisal/-a zoc » 26 Nov 2019, 23:44

Imam STM32L476, v njem nastavljen TIM2, da pošilja testni buffer in števec na USB (npr 60 Bytes ali 230 Bytes).
Uporabljam HAL driverje, zadnje firmware knjižnice. TIM2 uporablja prekinitev s prioriteto 6, USB nastavljen kot CDC pa s prioriteto 3. Ko se timer izteče, se iz HAL_TIM_PeriodElapsedCallback kliče CDC_Transmit_FS (na vsakih 100 do 1000Hz sprobano) pošlje fiksen buffer in povečan števec vsak nov cikel.

Ko berem podatke preko USB s python skripto (na win10) opazim, da se mi vsake toliko izgubi kakšen paket. Velikokrat se to dogaja periodično na vsakih 8364 vzorcev, ne glede na nastavljeno hitrost TIM2, ampak ne zmeraj.
Če zadevo laufam na debuggerju (uVision+nucelo) se izgubljeni paketi pojavljajo redkeje.
Primer izgubljenih paketov je na sliki viden z rdečo barvo, modra je 16bit števec.

Any ideas?
Priponke
izgube-usb.png
graf izgubljenih paketov in števec poslanih paketov
Uporabniški avatar
zoc
 
Prispevkov: 14
Pridružen: 18 Jan 2015, 01:42
Zahvalil se je: 7 krat
Prejel zahvalo: 2 krat
Uporabnika povabil: radix
Število neizkoriščenih povabil: 3

Re: TIM2 100Hz in CDC_Transmit_FS

OdgovorNapisal/-a Kroko » 27 Nov 2019, 01:38

STM ne pošilja podatkov, USB deluje tako, da jih PC zahteva.
Nekateri win 10 CDC gonilniki imajo hrošča. Pri hudi obremenitvi podatke sicer zahtevajo ampah jih ne obdelajo. Poskusi z win7, tam tega buga ni. Ali pa zamenjaj driver.
Druga možnost je, da je PC prepočasen in ne zmore pošiljati zahtev glede na nastavljen USB time frame. Nastavi višjo prioriteto niti/procesa, ki kliče USB. Jaz ponavadi naredim nit z visoko prioriteto zadolženo samo za USB transfer, ki bere/piše podatke v ciklični buffer. Tega potem "obdelujejo" druge niti, zraven pa spremljam zasedenost tega bufferja.
Čeprav bi bilo super USB ni realtime komunikacija.
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4828
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 690 krat
Prejel zahvalo: 1682 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: CDC_Transmit_FS

OdgovorNapisal/-a zoc » 23 Apr 2020, 11:59

Zgleda, da problem povzroča "reset_input_buffer()" funkcija (pySerial) v while zanki na host strani. Brez nje ni več izgub. :)

Me pa sedaj zanima, zakaj dobim v terminalu, samo prvi buffer, če npr. dvakart zapored kličem CDC_Transmit_FS(buff1, 2), CDC_Transmit_FS(buff2, 2) z ukazom preko usb. Testni ukaz je tak, da pošljem dva bajta, prvi poljuben, drugi 0x52, ki izvede switch primer. Dobim oba buffra, če dam funkciji v glavno while zanko in se potem priklopim na USB s terminalskim programom. Uporabljam HAL driverje na STM32L4.

Koda: Izberi vse
void cmd_proc(uint8_t* buf, uint32_t *len)
{
   for(i=0; i<*len; i++)
   {
      cmdBUF[i] = buf[i];
      printf("cmdBUF[%d] = %X\r\n", i, cmdBUF[i]);
   }
   switch(cmdBUF[1])
   {
      case 0x52:
            test_usb();
            break;
       default:
            printf("DEBUG_MSG:Invalid command code received from host \r\n");
            break;
   }
}


Če odkomentiram reset hdc->TxState, dobim samo drugi buffer, če pustim kot je, pa samo prvi.
Torej, kakor, da bi mi nekaj blokiralo prenos(terminal, irq..?)
Je morda mišljen driver/prenos tako, da za eno pošiljanje preko hosta, dobim samo en odgovor al mi manjka nekaj, da dovolim, sprostim pošiljanje še naslednjega paketa?

Koda: Izberi vse
void test_usb(void)
{
   /* USB Device Core handle declaration. */
   //USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
   CDC_Transmit_FS(bl_test1, 2);
        //Hal_Delay(200);
   //hcdc->TxState = 0U;   
   CDC_Transmit_FS(bl_test2, 2);
}


Koda: Izberi vse
To imam v usbd_cdc_if.c:

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
  /* USER CODE BEGIN 6 */
  USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
  USBD_CDC_ReceivePacket(&hUsbDeviceFS);

   /* process USB commands */
   cmd_proc(UserRxBufferFS, Len);
   
  return (USBD_OK);
  /* USER CODE END 6 */
}

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
  uint8_t result = USBD_OK;

  /* USER CODE BEGIN 7 */
   //memcpy(UserTxBufferFS, Buf, sizeof(char) * Len);
  USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
  if (hcdc->TxState != 0){
    return USBD_BUSY;
  }
  USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
  result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
   
  /* USER CODE END 7 */
  return result;
}

Uporabniški avatar
zoc
 
Prispevkov: 14
Pridružen: 18 Jan 2015, 01:42
Zahvalil se je: 7 krat
Prejel zahvalo: 2 krat
Uporabnika povabil: radix
Število neizkoriščenih povabil: 3

Re: TIM2 100Hz in CDC_Transmit_FS

OdgovorNapisal/-a tilz0R » 25 Apr 2020, 14:57

Kot je rekel Kroko, host sprašuje (bolj kot ne) za nove podatke s strani device-a. Ti s tem ko kličeš funkcijo USB_Transmit_FS, bolj kot ne nastaviš pointer na podatke za poslat in potem se te pošljejo, ko host vpraša po njih. Ti si dvakrat klical isto funkcijo eno za drugo, kar efektivno overwrite-aš naslove.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1841
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 230 krat
Prejel zahvalo: 521 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: TIM2 100Hz in CDC_Transmit_FS

OdgovorNapisal/-a zoc » 08 Maj 2020, 00:30

Ja, bi treba bolj nastudirat tale USB. Stvar sem zaenkrat resil tako, da sem v poiskal kje se prenos konca (hcdc->TxState) in tam dodal eno funkcijo, s katero sem potem (po potrebi) klical CDC_Transmit_FS, tako da imam en mal ping-ponga med host-device.

Koda: Izberi vse
      hcdc->TxState = 0U;
      /* finished USB transfer cb */
      if(usb_tx_ok == 1)
      {
        usb_ack_cb();
      }

Trenutna resitev ni najboljsa, saj je to v usb knjiznjici (usbd_cdc.c).
Uporabniški avatar
zoc
 
Prispevkov: 14
Pridružen: 18 Jan 2015, 01:42
Zahvalil se je: 7 krat
Prejel zahvalo: 2 krat
Uporabnika povabil: radix
Število neizkoriščenih povabil: 3


Vrni se na ARM-Cortex-M

Kdo je na strani

Po forumu brska: 0 registriranih uporabnikov in 1 gost