How to correctly handle USB_CDC communication? Topic is solved

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: RoccoMarco, barthess

User avatar
arbulgazar
Posts: 8
Joined: Sun Dec 16, 2018 5:12 pm
Has thanked: 1 time

How to correctly handle USB_CDC communication?

Postby arbulgazar » Wed Feb 27, 2019 10:14 pm

Greetings! I am developing a project based on STM32F406Discovery board which boils down to communication via USB with the application on the PC (connected via mico-usb to stm board).
For that, I have 2 threads - for reading and writing. Writing thread is supposed to be spamming USB with a status messages. Reading thread is supposed to read occasional commands from main PC. Now the problem I have is that reading is sometimes not working and I don't have enough knowledge to understand the reason. I suspect that this is due to the spamming of the write-thread. Essentially it is fine to lose some status-spam messages but it is crucial to process all the incoming messages. I am not sure if I did everything correctly on my side, or is that the application on the main PC side to blame. Should I use interrupts for when there is reading available on the bus? What should I look for to make this fail-safe?

As a project startup, I used demo provided in chibios_trunk\testhal\STM32\multi\USB_CDC with ChibiOS 18.2.
Here is a narrowed-down code that should give a good understanding of how I do this.

Code: Select all

THD_FUNCTION(readThrFunction, arg)
{
  (void) arg;
  chRegSetThreadName("Read thread");
  char readBuffer[128];
  event_listener_t usbData;
  eventflags_t flags;
  int bytesRead = 0;
  chEvtRegisterMask((event_source_t *)chnGetEventSource(&PORTAB_SDU1), &usbData, EVENT_MASK(1));
  while (TRUE)
  {
    chEvtWaitAll(EVENT_MASK(1));
    flags = chEvtGetAndClearFlags(&usbData);
    if (flags & CHN_INPUT_AVAILABLE)
    {
      bytesRead = chnReadTimeout(&PORTAB_SDU1, readBuffer, 64, 1000);
      doStuff();
    }
  }
}

THD_FUNCTION(writeThrFunction, arg)
{
  (void) arg;
  chRegSetThreadName("write thread");
  char payloadBuffer[64];
  int payloadLength = 0;
  while (TRUE)
  {
    getSomeUsefullStuff(...);
    chnWriteTimeout(&PORTAB_SDU1, payloadBuffer, payloadLength, 10);
    chThdSleepMilliseconds(10);
  }
}

static THD_WORKING_AREA(readThrWA, 1024);
static THD_WORKING_AREA(writeThrWA, 1024);
main()
{
  ... // initialization stuff
  chThdCreateStatic(readThrWA, sizeof(readThrWA), HIGHPRIO, readThrFunction, NULL);
  chThdCreateStatic(writeThrWA, sizeof(writeThrWA), NORMALPRIO, writeThrFunction, NULL);
  while (true) {
    chThdSleepMilliseconds(10);
  }
}

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: How to correctly handle USB_CDC communication?

Postby Giovanni » Thu Feb 28, 2019 12:19 pm

Hi,

Try the "USB RAW" demo, it could be closer to what you need. It uses USB directly without the buffering (that you don't need probably).

Giovanni

User avatar
arbulgazar
Posts: 8
Joined: Sun Dec 16, 2018 5:12 pm
Has thanked: 1 time

Re: How to correctly handle USB_CDC communication?

Postby arbulgazar » Thu Feb 28, 2019 3:33 pm

Hi! Thanks for answering. I need serial over USB though. What is the disadvantage of having a buffer in my case?

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: How to correctly handle USB_CDC communication?  Topic is solved

Postby Giovanni » Thu Feb 28, 2019 4:49 pm

In both cases it is a CDC device, it depends if you want buffered read/write or not. If it is unbuffered then read/write return when the operation is complete, not immediately.

Just look at the demo.

Giovanni


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 11 guests