Problems with communicating with Linux hosts.

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

Moderator: RoccoMarco

Post Reply
chibby
Posts: 66
Joined: Wed Oct 22, 2014 11:20 am

Problems with communicating with Linux hosts.

Post by chibby »

Hi,

I recently reported issues using USB-CDC on the OTG port of 407-DISCOVERY board. Apparently others have reported issues with Linux hosts in the past that have remained unresolved.
viewtopic.php?f=16&t=2264&start=20

I don't like this sort of 'not tested on linux' situation, so I've decided to dig into this a bit.

I have found that the DISCOVERY-MEMS demo does work from the debugger.

Starting the elf file under GDB produces a ttyACM device in the system logs

Code: Select all

<gdb> monitor reset halt


dmesg output:

Code: Select all

[47173.523020] usb 2-4: Manufacturer: STMicroelectronics
[47173.523025] usb 2-4: SerialNumber: 310
[47173.526233] cdc_acm 2-4:1.0: ttyACM0: USB ACM device
[83375.156060] cdc_acm 2-4:1.0: failed to set dtr/rts


Note that this is different to the "-110" power related errors I got when running outside the debugger where the device failed or did not even appear at all.

Now letting it run, the failed device gets deleted, a new one created; the <ch> command shell appears and the accelerometer demo works:

Code: Select all

<gdb> continue

Code: Select all

[83775.954971] usb 2-4: USB disconnect, device number 11
[83775.957994] cdc_acm 2-4:1.0: failed to set dtr/rts
[83777.331040] usb 2-4: new full-speed USB device number 12 using ohci-pci
[83777.524840] usb 2-4: New USB device found, idVendor=0483, idProduct=5740
[83777.524855] usb 2-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[83777.524862] usb 2-4: Product: ChibiOS/RT Virtual COM Port
[83777.524868] usb 2-4: Manufacturer: STMicroelectronics
[83777.524873] usb 2-4: SerialNumber: 310
[83777.529350] cdc_acm 2-4:1.0: ttyACM0: USB ACM device


The following is from a minicom terminal:

Code: Select all

AT                                                                                
AT ?                                                                             
ch> AT
AT ?
ch> ~x�~~x�~
~x�~~x�~ ?
ch>                                                                               
ch>         
ch>
ch> help
Commands: help exit info systime mem threads test
ch> systime
21651772
ch>


The simple fact of halting it in the debugger may suggest this is a timing issue. In any case it doesn't look like big issue to fix. The rest of the demo, the device and the shell is stable one it is up.
Last edited by chibby on Tue Dec 22, 2015 11:10 am, edited 1 time in total.
chibby
Posts: 66
Joined: Wed Oct 22, 2014 11:20 am

Re: Problems with communicating with Linux hosts.

Post by chibby »

I think I have resolved it. ;)

Further digging revealed that there is a deamon running to pickup new modems devices. Stopping this service removes the startup issue with the MEMS demo .

Code: Select all

 systemctl stop ModemManager 


So it seems that when this daemon starts reacting to the presence of a new device it initiates some communication with /dev/ttyACM0 that locks up ChibiOS.

Halting the board using the debugger allowed this process to give up and the terminal software then worked OK with ChibiOS USB-CDC.

So it's blame game. Is there something that an ACM device should be able to respond to without falling over? My guess is that this software is pinging the new device with an AT command to probe it. It probably should be able to handle that sort of thing in a stable and transparent manner.

Minicom was also sending AT and some probing that the CibiOS device manages to echo back with a question mark, so this may be at a lower level, maybe there's a clue in the DTR/RTS message.

Any thoughts?
chibby
Posts: 66
Joined: Wed Oct 22, 2014 11:20 am

Re: Problems with communicating with Linux hosts.

Post by chibby »

This may explain the line errors I was getting before disabling the ModemManager . This requirement beyond the basic minimum ACM standard could well be the root cause of the Linux host issues.

Code: Select all

static int cdcacm_control_request(usbd_device *usbd_dev,
   struct usb_setup_data *req, uint8_t **buf, uint16_t *len,
   void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
   (void)complete;
   (void)buf;
   (void)usbd_dev;

   switch (req->bRequest) {
   case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
      /*
       * This Linux cdc_acm driver requires this to be implemented
       * even though it's optional in the CDC spec, and we don't
       * advertise it in the ACM functional descriptor.
       */
      return 1;
      }
   case USB_CDC_REQ_SET_LINE_CODING:
      if (*len < sizeof(struct usb_cdc_line_coding)) {
         return 0;
      }

      return 1;
   }
   return 0;
}


https://github.com/libopencm3/libopencm ... m/cdcacm.c

If some can show how this can be added to ChibiOS , I will test be able to test it.
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Problems with communicating with Linux hosts.

Post by Giovanni »

Not all messages are handled by the Serial_USB driver:

Code: Select all

/**
 * @brief   Default requests hook.
 * @details Applications wanting to use the Serial over USB driver can use
 *          this function as requests hook in the USB configuration.
 *          The following requests are emulated:
 *          - CDC_GET_LINE_CODING.
 *          - CDC_SET_LINE_CODING.
 *          - CDC_SET_CONTROL_LINE_STATE.
 *          .
 *
 * @param[in] usbp      pointer to the @p USBDriver object
 * @return              The hook status.
 * @retval true         Message handled internally.
 * @retval false        Message not handled.
 */
bool sduRequestsHook(USBDriver *usbp) {


Implementation of extra messages, there are dozens of them, is up to the application by defining its own hook function.

Giovanni
chibby
Posts: 66
Joined: Wed Oct 22, 2014 11:20 am

Re: Problems with communicating with Linux hosts.

Post by chibby »

Thanks Giovanni.

I realise that the OS just provides a minimal subset and it appears that Linux acm_cdc requires one more than the official minimum. However, if that is the case, having that little extra in ChibiOS to prevent it hanging when sees a Linux host would be good , wouldn't it?

Do you agree that this control line issue could be what is causing the Linux host problems?
mobyfab
Posts: 484
Joined: Sat Nov 19, 2011 6:47 pm
Has thanked: 21 times
Been thanked: 31 times

Re: Problems with communicating with Linux hosts.

Post by mobyfab »

Hey,

This is what I use to handle special requests.

Code: Select all

#define CDC_SET_LINE_CODING             0x20
#define CDC_GET_LINE_CODING             0x21
#define CDC_SET_CONTROL_LINE_STATE      0x22

static cdc_linecoding_t linecoding = {
  {0x00, 0x96, 0x00, 0x00},             /* 38400.                           */
  LC_STOP_1, LC_PARITY_NONE, 8
};

/* Our special request hook handles RS232 flow control commands */
static bool sduSpecialRequestsHook(USBDriver *usbp) {

  if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) {
    switch (usbp->setup[1]) {
      case CDC_GET_LINE_CODING:
        usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL);
        return TRUE;

      case CDC_SET_LINE_CODING:
        if (usbp->setup[4] == sizeof(cdc_linecoding_t))
        {
          memcpy(&linecoding, &usbp->setup[5], sizeof(cdc_linecoding_t));
        }
        usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL);
        return TRUE;

      case CDC_SET_CONTROL_LINE_STATE:
        if (usbp->setup[2] & 1) /* DTR */
        {
          // Set DTR
        }
        else
        {
          // Unset DTR
        }
        if (usbp->setup[2] & 2) /* RTS */
        {
          // Set RTS
        }
        else
        {
          // Unset RTS
        }
        return TRUE;
      default:
        return FALSE;
    }
  }
  return FALSE;
}
chibby
Posts: 66
Joined: Wed Oct 22, 2014 11:20 am

Re: Problems with communicating with Linux hosts.

Post by chibby »

Thanks moby.

Are you saying that dummy structure is enough, ie you just need to return true and do nothing?
mobyfab
Posts: 484
Joined: Sat Nov 19, 2011 6:47 pm
Has thanked: 21 times
Been thanked: 31 times

Re: Problems with communicating with Linux hosts.

Post by mobyfab »

In my case I do return the data asked by the OS with usbSetupTransfer(), so it should work fine.
chibby
Posts: 66
Joined: Wed Oct 22, 2014 11:20 am

Re: Problems with communicating with Linux hosts.

Post by chibby »

I presume you mean the ACM driver on the HOST machine. Is that correct?

In which case maybe this could fix the Linux host issue, if some could provide a code snip that actually does it, the idea could be tested. I don't know what DTR/RTS means in the context of ACM but it seems that Linux kernel is expecting it. Virtual control lines on a virtual com port seems a very fuzzy concept.
mobyfab
Posts: 484
Joined: Sat Nov 19, 2011 6:47 pm
Has thanked: 21 times
Been thanked: 31 times

Re: Problems with communicating with Linux hosts.

Post by mobyfab »

It makes sense if you are building a USB to Serial adapter. You can configure the serial line directly from the OS.

Just adapt the code I posted earlier, it's all that you need.
Post Reply