Custom Legato Yocto USB Serial Port



I have a scenario where a WP8548 modem communicates with a Peripheral Serial Device over a UART (via a Legato app - this is working), but also need for the Peripheral Serial Device to communicate directly with a Host PC via a virtual serial COM port over the modem’s USB 2.0 OTG Port.

I’ve attached this diagram to help illustrate what I’d like achieve.

Legato enumerates a number of USB endpoints during the boot sequence, some of which are virtual serial ports.

My questions are as follows:

  1. Is it possible to add another custom USB serial port endpoint?
  2. How can this be achieved? Do I need to implement a Linux Gadget Serial Driver?
  3. Can one of the existing USB endpoint be used/repurposed for this (Raw Data Port?)?

Any advice would be greatly appreciated.



Hi again.

Is anyone able to answer my questions above?




I need the same functionality. Send raw data over the USB port of WP85.

Thanks to provide the guide lines to do it



Any chance of getting a response to this at all?

The ability (or lack thereof) to do this is impacting on the hardware design.

Unfortunately, it needs to work like this (via virtual serial com port) as it must also integrate with a legacy system only supporting serial communications.

Note: the ‘virtual serial port’ doesn’t exactly need to be directly linked with UART1. It could also be routed there via the App - the App could be a Comms Server for UART1.

If this feasible? Or is it embedded in the WP8548 firmware?

Thanks in advance,


Hi Raf,
If I understand well, you need to relay traffic between the serial gadget port and a physical serial port on the WP85. If you look at the script /usr/sbin/restartNMEA, it is doing something similar to what you need, except that it is relaying to the /dev/nmea port instead of a physical serial device. If you are not using NMEA, you can re-purpose ttyGS0 for what you need. In fact, replacing /dev/nmea with /dev/ in the above script would do the trick.

Hope this helps,


Hi Zoran,

Thanks for the help.

Yes, that’s correct. I have no need for /dev/nmea so replacing it with another fd/port is a good idea.

I tried what you suggested but it didn’t seem to work. Perhaps I’m just misunderstanding something, though?
Here’s what I did:

  1. Edited /usr/sbin/restartNMEA and replaced all instances of /dev/nmea with /dev/ttyHSL1
  2. Saved the file and rebooted the mangOH board
  3. Opened up two terminals on the mangOH via SSH; one to /dev/ttyGS0 and one to /dev/ttyHSL1
  4. I was unable to observe messages relayed from either direction when typing in the terminals

I also tried /dev/ttyHS0 and /dev/ttyUSB1 (via a FT232R) which didn’t work either. Additionally. I tried running the script directly from a terminal which didn’t make a difference.

Note that I was editing /usr/sbin/restartNMEA over an SFTP connection in DS and received an error message when saving the file “Operation failed. File system input or output error”. However, when I reopen the file those changes appear to be saved. Maybe this is an issue?

Here’s what I can confirm:

  • A connection to Sierra Wireless NMEA Port in Windows and a terminal opened to /dev/ttyGS0 works. Messages go both ways.

  • A connection to the RS232 console port on mangOH and a terminal opened to /dev/ttyHSL1 works, too.

Any thoughts?



We needed this also, and Zoran’s advice is correct – but a simpler way is to just comment out the two lines in that refer to restartNMEA. Then there are no legato apps using ttyGS0 and you can use it for whatever you want. Your relay idea is nice, but you may need to write a small app that passes data between the two ports.

If this is the only USB interface you need, you can simplify it even further by creating /etc/legato/usbmode that has only “nmea” in it; i.e. echo nmea > /etc/legato/usbmode
After you do that the module will only present one USB serial interface to an external host. and you lose the ability to ssh in over the cdc-ecm interface.


Thanks for the suggestions @dcdatdrivecam. I wasn’t aware of

I’m back in the office now so I can finally try to sort things out. Several of the other USB interfaces are useful so I’ll leave /etc/legato/usbmode as is.

I’ve been successful in making a reliable software ‘bridge’ between /dev/ttyHSL1 <> /dev/ttyUSB1 via an app that opens the ports and runs a script very similar to It’s fine for proof of concept but ultimately I really need to bridge between /dev/ttyGS0 (specifically, Sierra Wireless NMEA Port in Windows) and some other port on the WP8548 - this is where I’m having trouble.

There’s something odd with /dev/ttyGS0 - something else is interacting with it even with the changes to as you suggested.

For simplicity, I’ve listed basic test scenarios that highlight the problem using terminals only.

I’ll begin with what works first:

  1. Open Sierra Wireless NMEA Port in Windows.
  2. ssh into mangOH
  3. Send this from mangOH: echo "Hello" > /dev/ttyGS0
  4. Message is received correctly on Sierra Wirelss NMEA Port

There seems to be a problem going the other way though:

  1. Open Sierra Wireless NMEA Port in Windows.
  2. ssh into mangOH
  3. Run this on mangOH: cat /dev/ttyGS0
  4. Messages sent from Sierra Wireless NMEA Port aren’t (always*) received by /dev/ttyGS0.

*If I send preassembled messages (of any length) from Windows to /dev/ttyGS0, nothing shows up. However, if I hold down a key on the keyboard, suddenly (after 30-40 individual and sequential characters) traffic starts flowing from Windows to /dev/ttyGS0.
Additionally, once the traffic starts flowing, if I close the comms port on Windows I receive $GPS_STOP on /dev/ttyGS0. If I then reopen the comms port on Windows /dev/ttyGS0 receives $GPS_START. I haven’t been able to track down where this is coming from (I hope it’s not built into the SWI comms port driver for Windows :worried:).

It would appear as though the repeated keystrokes with fast enough delays between them ‘wake up’ the transmission side of /dev/ttyGS0, or whatever is responsible for controlling the $GPS_ messages. By slowing down my keyboard’s character repeat rate enough I can observe that traffic is never sent out from /dev/ttyGS0.

Did you experience anything like this when using /dev/ttyGS0 for your own purposes?

@zmarkovic do you know of any other service that would still be using /dev/ttyGS0? Is the port configured by any SW scripts? Is the input to /dev/ttyGS0 buffered internally by something? Can you explain this behaviour?





So I I’ve found the ‘other’ source interfering with /dev/ttyGS0 - it was caused by after all!

Turns out I mistakenly edited /etc/init.d/ which (I think) I should have been editing in /mnt/flash/ufs/etc/init.d/ I’m not sure exactly where the ‘real’ file lives but the changes I made initially weren’t taking effect. I ended up modifying the one in /etc/rcS.d/ and that worked.

I noticed this message “nmea: smd opened” on the debug console during kernel boot which got me curious and eventually tracked it back to some code in /etc/init.d/rcS.

Ultimately, /dev/ttyGS0 was forwarded back and forth between both /dev/nmea and some other /dev/ I was using and causing the conflicts I observed.

As for the source of $GPS_START and $GPS_STOP messages, I’m fairly confident they are built into the Sierra Wireless NMEA Port driver for Windows and transmitted automatically upon opening and closing the port. Can anybody confirm this for me?



Glad you solved your problem, Raf. The overlay/union file system caused me some grief when trying to edit some startup scripts, also. Basically, until the unionfs is mounted after S04mount_unionfs is executed in rcS, you’re running with the original, base filesystem. After that, scripts that you’ve modified will have the changes you made. However, if you want to modify inittab, you have to modify an rcs script that runs after S04mount_unionfs and insert a kill -HUP 1. this forces init to re-read inittab and it will then pick up your changes. I’ve used that to start pppd at startup on the internal ttyGS0

Can’t help you with your Windows questions: all our development is on Linux or microcontroller RTOSs


Thanks for the explanation @dcdatdrivecam. I’m still a novice when it comes to Linux development so the file system info is very useful to me.

As you suggested, I ended up having to write an app to handle the serial port bridge because I have another app that also needs to access one of those ports (when not in use). The bridge app makes use of the FD Monitor API and the Event Loop API. This works quite well, making the serial link fast and reliable. Those $GPS_ messages actually ended up being quite useful - I use them to signal when the Host opens and closes its port. A fd monitor on the serial gadget listens for these messages and controls the link/bridge between both ports.

Now, the only thing left to do is detect when the USB OTG cable is disconnected from the Host. This could leave the bridge link open indefinitely because /dev/ttyGS0 is persistent and the bridge app will block my other App from accessing one of the ports it needs.

I can see these message in the Kernel log:
msm_otg msm_otg: USB in low power mode
msm_otg msm_otg: USB exited from low power mode

Is there a way to detect this from a Legato application? Can I monitor anything?

The bridge app has the highest priority in terms of port access, but I need an alternate method of knowing when the Host has disconnected other than via $GPS_STOP, which will not be received if the user simply pulls the USB cable out.



Is there a way to detect this from a Legato application? Can I monitor anything?
i hava same problem, now do you find solution?