2
votes

I have an embedded control that uses a STM32 Microcontroller which uses its USB port to communicate with the computer as a 'virtual COM port'. I am currently running a cycle test where the control is automatically cycled on for 5 minutes and off for 10 seconds. This is to catch an error that will appear every 50-200 restarts.

The device is already outputting debug messages through the Virtual COM Port, but when the device restarts, the USB device disconnects and reconnects. Then whatever program I was using to monitor the output (putty, Tera Term, etc.) loses connectivity and I must manually unplug and replug the USB cable and restart whatever COM application I am using.

My goal is to set up Tera Term or putty to keep the COM port open and just write the entire session to a log file, but because of the restart the USB device isn't persistent.

Is there any way that I can 'virtualize' the USB port or modify the .ini file in anyway to make the USB port persistent? Here is what I believe is the relevant section of the .ini file

[USBtoSer.nt.Services] 
AddService=usbser, 0x00000002, DriverService

[DriverService] 
DisplayName=%USBIOMport% 
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\usbser.sys 

I cannot modify the embedded application running on the STM32 and can only interact with it through a pre-programmed terminal via the USB

EDIT: Here is a link to information from Microsoft that explains what the above does. I haven't had any luck determining which change would work for my application, so I may start trial and error with different ErrorControl and StartType (though from what I read, I hardly doubt they will solve my issue)

1
Since you are constrained to using a terminal written by someone else, with no changes of your own, nor any changes to the embedded code, this problem has no programming component at all. You might try SuperUser.Ben Voigt
Thanks for the recommendation @BenVoigt, I may do that. I certainly don't HAVE to use a different terminal, I could write my own, but that still doesn't solve the problem of the device non-persistence. Are you suggesting that I could write my own program to just keep actively keep polling the USB port?StephenH
If you wrote your own program, you could handle the OS event related to device removal and close the port. Then when the device came back, it wouldn't find its preferred port in use, and would reclaim it. You'd get an event for device connection as well, indicating that it is again time to open the port.Ben Voigt
Thanks @BenVoigt, I figured there might be a way to do that programmatically, I was just looking for an easy solution without rolling my own serial logger. If I don't have any luck on SuperUser, I'll probably be back here asking a different question :-)StephenH

1 Answers

2
votes

Just realized I never posted an answer for this. Turns out it was an issue with the USB Virtual COM driver that I was unable to resolve, but I was able to come up with this work around.

Note: This question and answer are Windows platform specific.

Microsoft provides a program called devcon.exe. It's the Windows Device Console, kind of a command line version of Device Manager.

Ultimatlely, once I found that I could remove the device and rescan (without unplugging it, so sort of "virtually" unplugging it), I realized I could make a call to this application to remove the specific device for me and then rescan the device structure if I ever detected a disconnect. So here is the python snippet I used to accomplish this in between dumping the serial data. Probably not the cleanest code ever, but this was only for a quick and dirty logging script. Hopefully this can help some of you experience the same issue.

import serial
from subprocess import call
from time import sleep

def remove(ser):
    try:
        ser.close()
    except:
        print "Could not close port"
    call(["devcon.exe","remove","USB\VID_0D59&PID_0005*"])

def rescan():
    call(["devcon.exe","rescan"])
    sleep(30)

def send(ser, message):
    if ser.isOpen():
        try:
            ser.write(message)
        except serial.serialutil.SerialException:
            remove(ser)
            rescan()
            try:
                ser.open()
            except serial.serialutil.SerialException:
                try:
                    remove(ser)
                    rescan()
                except:
                    print 'Could not reconnect'
                    return False
            else:
                print 'Reconnected to %s' % (ser.portstr)
                ser.write(message)
                return True
        else:
            return True

Important notes: attempting to send data to the port and then recieving the exception was the only way to tell that the device had restarted. No amount of open, closing, or checking connections proved succesful with this driver, so this was the best solution that I could come up with at the time.

Also, note the arbitrary 30 second delay in the rescan() function. This was to allow the computer enough time to recognize the device and find the appropriate drivers. The time varies per system and device.

This code snippet is Python 2

Finally, this is probably obvious, but this solution has devcon.exe in the same directory or in the PATH