Understanding usb and uploads


Project maintained by profezzorn Hosted on GitHub Pages — Theme by mattgraham

Any processor that has a direct USB connection can pretend to be anything. It can work like a mouse, a keyboard, a drive, a microphone, a serial port, or any combinations of these things. Every USB device has a descriptor. The descriptor is just a chunk of data that is downloaded from the device when you first connect it. The descriptor tells the OS what kind of device is connected. The descriptor has a list of end points in it. Each end point ends up becoming a separate device on the host computer. This is how a USB device can implement multiple devices as the same time.

The descriptor depends on the program that is uploaded. For instance, in ProffieOS, you can select which endpoints to make available in Arduino -> Tools -> USB Type. Usually, what you want to select is "Serial + WebUSB + Mass storage", which means that there will be three endpoints. One that looks like a serial port, one that looks like a WebUSB endpoint, and one that looks like a drive. The descriptor also provides some other information, like who made the device, what it's called and so forth. All this information can be changed by reprogramming the device.

If the program running on the Proffieboard is not working properly, either because the program has a bug in it, or because it was corrupted somehow. Then the computer may be unable to communicate properly whith the board. This may happen even before it downloads the descriptor, in which case the computer won't even be able to identify the board at all. Without doing something about it, the computer will be unable to communicate with the board when this happens.

Fortunately, Proffieboards have a fall-back option called "bootloader mode". This is simply another program programmed into the board which cannot be changed. The bootloader code is a part of the CPU, and is not special to Proffieboards. Any board that uses a STM32 processor will have a similar bootloader. By holding BOOT while the board is booting (which we can make it do by pressing and releasing RESET), we can tell the board to ignore any uploaded program, and run the bootloader code instead.

When the board is running in bootloader mode, it doesn't actually know that it is a Proffieboard, and the descriptor it presents to the OS is very different. It calls itself "STM32 BOOTLOADER", and it only has one endpoint. That endpoint is a special device called a "DFU" device. It's not a standardized device, which is why we sometimes needs to install a special driver to be able to talk to it. On windows, this is accomplished by using Zadig. Note that the operating system has no idea that the "STM32 BOOTLOADER" and the "Proffieboard" are actually the same physical device. To the computer, it looks like you disconnected the Proffieboard and connected some other device. This is why you cannot run Zadig on the Proffieboard device and expect it to work when the Proffieboard is in bootloader mode. Any changes applied to one of these devices does not affect the other at all.

Uploads 🔗

Normally, when you upload a program from Arduino, both the "ProffieOS" device, and the "bootloader device" comes into play. It goes something like this: When you hit upload in Arduino. Arduino will check what port you selected under Arduino -> Tools -> Port. Then it will send a special sequence to that port which is intended to cause the connected board to reboot into bootloader mode. This sequence is the same for nearly all Arduino boards. Once the reboot happens, the port goes away. Arduino then proceeds to run the upload program, which is not the same for all boards. The Proffieboard upload programs waits until the board has rebooted and the computer has identified the bootloader device. If this takes a long time, or if it fails for some reason, you'll seee a 1-10 countdown in the Arduino window, and the upload will fail. Once the bootloader device bcomes available, the upload process starts, and you'll see a 0-100% progress bar in the Arduino window. Once the upload is done, the board is rebooted again, but this time, it starts the new program that was just uploaded. If everything goes well, the board plays a boot sound and the port shows up in Arduino -> Tools -> Port again.