Detect presence of USB stick in bootloader of F28M36x microcontroller - bootloader

We have developed a bootloader for a F28M36x Concerto microcontroller (Texas Instruments), which loads the software from a USB stick.
We have integrated the USBlib in the bootloader (see API guide here).
The boot from USB stick works; however it takes very long time to detect USB pen drives with high capacity. To be precise, it takes long time to get the event "MSC_EVENT_OPEN" in the callback MSCCallback() function that is passed to the API USBHMSCDriveOpen()
g_ulMSCInstance = USBHMSCDriveOpen(0, MSCCallback);
Currently, this is the first event that allows the bootloader understanding that a pendrive is present.
So, we have set a timer of about 5 seconds: if the MSC_EVENT_OPEN event is triggered before the timer expires, then the bootloader loads the SW application from USB. If the timer expires without having detected any USB driver, it loads the software from the flash. So the problem is that the boot of the software after power on takes long time, because it waits in vain for the presence of a USB pendrive, which in 99% of cases is not plugged in.
So the question is: is it possible (by calling a proper USBlib API or in any other way), to understand immediately that a USB pen drive is plugged in? If we could make a fast detection of the USB drive, we would avoid waiting 5 seconds in vain: if the USB pen drive is not physically present, the bootloader would start immediately loading the application from the flash.

Related

Bulk USB device connection and programming

Some background on my issue, my company sells single-use short life battery powered USB devices that certain customers require a certain 'profile' config programmed into the device before shipping. We currently sell them in batches up to 2000. Each one is plugged into a computer(Windows) with our configuration software running, the device is auto detected and then notified when completed. Takes roughly 10-15 seconds per USB device. No input is required on the computer besides inserting the device.
As you can imagine this is a very slow process that is increasing in frequency. The device shows up as mass storage device with about 100kb of storage. All devices have the same name when showing in My Computer. The issue is the programming software does not detect if multiple devices are plugged in, only loading the profile onto the first device plugged in.
Looking for a possible suggestion/solution to improve the speed of configuring these devices? My scratch pad idea was to buy 10-20 port USB hubs and possibly look at enabling one port in sequence every 20 seconds either with hardware buttons or software setup.
I'm not sure if this will work with your programming software, but since the devices present themselves as USB Mass Storage devices, you might be able to plug a bunch of them in at once, then use a script to dismount them all and mount only one device at at time. A one technique to do that is to use the mountvol command.
To unmount a drive
mountvol [DriveLetter] /p
To mount a drive
mountvol [DriveLetter]
Source:
https://superuser.com/questions/704870/mount-and-dismount-hard-drive-through-a-script-software
Another option would be to bypass the programming software entirely. You could use the programming software once to figure out what it is doing to the device (I would guess it's just copying some config file onto the drive). Once you know what it's doing, write your own script that can handle many devices in parallel.

Serial Mouse device crashes using virtual desktop

I have some old serial based USB touchscreen systems that would be expensive to replace with new hardware.
They are connected in the following manner:
Serial Mouse -> Serial to USB adapter -> Thin Client -> Virtual Machine
Everything works great with one issue. I'm experiencing a driver crash everything user either logs off, shutdown, or reboots. The current workaround has been to disable the serial mouse device before logging off which is a real pain. As long as the device is disabled, everything works great.
I did a lot of research on this issue by taking memory dumps of the crash virtual machines.
It seems like when the user logs off, the USB device is abruptly disconnected and then Windows tries to disable the device gracefully and waits until it is confirmed, thus hanging forever. In assembly it appears to call a .sys file that never returns back.
Is there anything that can be done with an issue like that? Can you change the device shutdown order? Or perhaps tell Windows to not ensure the plug and play device is shutdown? I doubt the vendor would be willing to change their driver.
I wrote a custom solution to this problem.
The application uses the ShutdownBlockReasonCreate API call to block Windows from shutting down. It then listens for reboots or logoffs using the WM_QUERYENDSESSION API call. When it gets this, it disabled the devices and then destroys the shutdown block created.
A real pain but it works

Dynamag USB card reader slow on keyboard mode in OSX

My question is regarding credit card readers configured in Keyboard mode under OS X. I've noticed that the same reader running under OS X (I'm running 10.9.4, but the same holds true for previous versions) reads out swipe data about twice as fast in Windows 7 as it does on the Mac. For example, if I swipe a card using my MagTek Dynamag reader in to Text Edit (or any app) on the Mac, it can take a good 4-5 seconds to fully output the track data (the track is quite long because it's encrypted). If I run the same swipe using the same computer and reader using my VMWare Fusion Windows 7 virtual machine, the swipe outputs in a text file in about half the time (2-3 seconds). Even with whatever overhead is introduced by running a virtual machine, the output rate is still MUCH faster under Windows.
I originally just thought it was the reader that was slow until I tested it in Windows. Does anyone know what is causing the slower output rate on the Mac? Is it merely a setting or something more involved (such as USB drivers)? Thanks for any help!
I believe this may be a combination of the OS USB drivers and the polling interval setting on the device. Some of the MagTek devices, Dynamag and IPAD included, have a polling interval setting which dictates how quickly the data is ouputted to ensure there is no "skipping" when the data is read.
Reference:
Dynamag Tech Reference - actual page 8
"Programmable USB Interrupt In Endpoint polling interval"
USB HID Swipe Reader - actual page19
"The device has an adjustable endpoint descriptor
polling interval value that can be set to any value in the range of 1ms to 255ms. This property
can be used to speed up or slow down the card data transfer rate."

USB linux gadget zero driver communicate with Windows host

I need to set up USB communication between a Windows 7 host and a Linux device for data transfer. I was able to compile the Linux kernel on the device to include the Gadget Zero driver in the kernel (not as a loadable module - Linux version 3.0.15). My project has some requirements, which also explains why I chose Gadget Zero:
1) On the Windows 7 host, a kernel mode driver must be used to communicate over the USB connection for sending and receiving bulk data. (speed is not important, not a lot of data at once).
2) On the linux device, no requirements on USB side except send and receive data easily over USB link. The data received will eventually be "unmarshalled" to call functions in another kernel module (and those responses packaged and sent back to the host).
3) Multiple linux devices will be connected to the host, so need easy way to enumerate connected devices and communicate with them.
So due to the requirements, I decided against the Gadget Serial. I'm having serious issues sending and receiving data over the virtual COM port in kernel mode (KMDF) in Win 7 host. WinUSB does not seem to want to open my attached device (I'm using KMDF windows USB driver from template in VS2012) Also, the gadget serial driver on the linux side, I cannot find the functions where the data is received and sent. Plus, any received data on the linux device seems to be echoed back to the host for some reason. (and to test this, I wrote a simple user-mode app in Windows, which is a no-no for my project).
Gadget Zero, it appears much simpler on the linux side. I can plug the USB cable to the Win7 host, and I can get the device to appear in the device manager. However, again I am having problems with getting communication going over the link. Gadget Zero has 2 bulk endpoints, so this shouldn't be an issue. Surely, someone has made data communication possible between a Windows host and a linux device using Gadget Zero? With Gadget Zero, it should be easy to enumerate the connected linux devices and communicate with them.
The trick is to keep the Windows side communication in kernel mode. Can someone point me in the right direction perhaps with Gadget Zero, Windows 7 KMDF, and some sample source code? I have a hard time believing no one has done this before because my internet searches don't turn up much. (and mostly user-mode solutions with Gadget Serial).
Thanks!
So you're writing a Win32 driver in which you want to communicate with your linuxed usb? I haven't written much win32 kernel code, but I believe I've seen a huge section in the doc, saying something like "This is how you make usb drivers"... That'd be it. In other words, when in kernel mode you have access to the full kernel usb layer. You don't need an existing driver or whatnot.
On the linux side you can use the serial gadget, in a different run mode. Only the default run mode, registers it self as VCP. There exist a more basic mode:
modprobe g_serial use_acm=0
Give it your own vendor id and you'll be able to attach your very own custom win32 driver. The 'multiple linux devices' will be handled by Windows. (Multiple instances of your driver, will be initiated.)
The echo you're seeing btw, is most likely a terminal feature. (The terminal mode on uarts will echo.) You have to disable it, when connecting. And now that you're at it, you also have to disable the xon/xoff, esc chars etc. (Standard legacy rubbish.)
And another thing. I'm not sure the gadget zero actually sends the data onto the line. It's meant for testing the gadget framework. (I could be mistaken though.)
Anyway, you've prolly solved this issue years ago. I'd be nice to know what you came up with.

How do I reset USB devices using the Windows API?

Do you know a way to use the Windows XP API to reset the USB bus? In other words, I'd like the OS to kick out any USB devices that are currently connected, and then auto-detect everything anew.
I'm aware of devcon, and I suppose I could do system calls out to it, but I'm hoping for a direct call into the API.
From kernel mode: You can force a specific USB device to be re-connected, as if it was unplugged and replugged again, by sending an IOCTL_INTERNAL_USB_CYCLE_PORT to its PDO. (This can only be done from a kernel mode, e.g. through a helper driver.) This 'cycle' operation will cause a USB reset to occur, after which the device would be re-enumerated. For example, if the device comes back with a different USB device descriptor, a different driver may be matched for it.
From user mode: You can do this by ejecting the device through the CfgMgr API. For example, to go over all USB hubs and eject all devices:
Find all devices having device interface GUID_DEVINTERFACE_USB_HUB with SetupDiGetClassDevs(... DIGCF_DEVICEINTERFACE).
Enumerate over the returned device information set (SetupDiEnumDeviceInfo).
For each device, get the DevInst member:
Invoke CM_Get_Child(DevInst) and then CM_Get_Sibling repeatedly to go over all child nodes of the hub (i.e. the USB devices).
For each child node, call CM_Request_Device_Eject.
Well, use can use the Setup API (SetupDiXXX functions) to enumerate the USB devices in the system, and then call WinUsb_ResetPipe on each one, but I'm not sure if that's what you're looking for. It's been a while since I worked with USB devices, but as I recall, there is no standard way to reset a device (i.e. simulate a power off/power on cycle). If it's possible for a particular device, you'd have to send an appropriate IOCTL (using DeviceIOControl) to the driver. The IOCTL would vary from manufacturer to manufacturer.
It's possible to cycle the parent port on the USB hub the device is attached to, as well. This will result in, among other things, apparrent unplug/replug actions, as you will see a balloon popup when this occurs.
Much of this is poorly documented, and honestly, I've gotten the impression there are only a handful of people at Microsoft who really understand it well. The design decision I've made for future devices I design is that I intend to include watchdog functionality on both sides, as well as a device-side full reset function. That way, if the device figures out it is confused, it can just cut its own power for a second and fully reset, if the host can't communicate with it, it could do the same thing, and if the device thinks everything is fine but the host knows better, the host could order it to reset.
There are at least three APIs worth looking into for this problem: the Setup API, the Config Manager API, and various WMI extensions. However, be cautious about diving into WMI if you intend to use an Embedded XP target, as you will have to include a lot of other things in your OS image you might otherwise not need.
As far as I know, there is no way to do this - you can issue a command to have PnP rescan the bus for new devices, but that isn't the same as issuing a bus reset.
Furthermore, just because from a hardware perspective you issued a bus reset doesn't mean that Windows will remove the PDOs that represent the children of the hub and redetect them; the USB bus driver can (and does) do just what I describe (i.e. issue hardware bus resets without disturbing the device tree), and only after the device doesn't respond does it issue the surprise removal and yank it from the tree.

Resources