How board detection and firmware flashing works - MobiFlight/MobiFlight-Connector GitHub Wiki

MobiFlight supports a wide range of connected boards, both official (like Arudinos) and unofficial (like custom PCBs or the Raspberry Pi Pico). During startup MobiFlight goes through a process of identifying connected boards, determining whether they are supported, verifying the installed and MobiFlight firmware. This wiki explains how that process works.

How supported boards are defined

Supported boards are defined using board.json definition files located in the Boards/ folder of the MobiFlight installation. Every supported board must have a corresponding board.json file to get detected by MobiFlight.

The board definition file includes a range of information about the board, including how to identify the board via USB VID/PID, how to flash it (if flashing is supported), the available pins, etc. The complete set of options is described in the mfboard.schema.json.

The list of supported boards is loaded by BoardDefintions.cs and the boards themselves are exposed via Board objects.

How boards are handled during startup

Step 1: Identifying boards that might be supported

MobiFlight uses WMI to request all connected COM ports. It then iterates over each COM port and checks to see whether the VID/PID for the device connected to the port is listed in one or more board definition files. For a board to be considered at this point its VID/PID must match against a VID/PID in at least one board definition file. If it matches against more than one board definition file the first matching file is used (this happens to be alphabetically by board definition file name).

When this process is complete MobiFlight has a list of COM ports that have connected devices that are supported by MobiFlight and a corresponding board definition file for each of those connected COM ports.

This process is done in MobiFlightCache.cs:getSupportedPorts(). The function contains copious comments to explain in detail what is going on.

Step 2: Testing to see if the firmware is already installed

After matching against a board definition file MobiFlight attempts to communicate with the board to retrieve basic MobiFlight firmware information. This is done by executing a GetInfo command and checking to see if a response is received.

This check is done in MobiFlightCache.cs:LookupAllConnectedArduinoModulesAsync().

As part of the GetInfo command MobiFlight will do a second attempt at matching the connected device against the board definition files. It is possible that many boards share the same VID/PID but are actually different board types. For example, an Arduino Pro Micro will have the same VID/PID as a custom PCB that uses the ATmega32u4 chip. To determine the connected device type more specifically the MobiFlightType value returned from the firmware is tested against the board definition files. If a match is found, then the board definition originally detected in step 1 is replaced with the board definition that matched by MobiFlightType.

This second board lookup is done in MobiFlightModule.cs:GetInfo().

Step 3: Flashing the firmware if it isn't installed

If step 2 failed to get a response to the GetInfo() command then MobiFlight assumes the board doesn't have the MobiFlight firmware installed on it. It then attempts to flash the firmware using the flash settings specified in the board definition file detected in step 1.

At the moment MobiFlight only supports flashing Arduino devices, however the code and board definition files are structured to allow flashing other devices types in the future.

The flash, based on settings in the board definition file, is done in MobiFlightFirmwareUpdater.cs:UpdateFirmware().

Handling ambiguous boards that don't have the MobiFlight firmware installed

There are several situations where a connected board will have a VID/PID that matches multiple board definition files but will not have the MobiFlight firmwre installed yet. In those cases MobiFlight doesn't know how to flash the board and will just try the settings from the first matching board definition file. In many cases (e.g. an Arduino Uno that has the same VID/PID as an Arduino Mega) this will fail.

To resolve this MobiFlight offers the option of flashing devices from the MobiFlight Modules dialog as well, via a context menu that lists all matching board definitions. The user can select the appropriate one for their board and then those settings get used to flash the device.

The method that returns the list of matching board definitions is BoardDefinitions.cs:GetBoardsByHardwareId().