Unique Device Identifiers

Electric UI uses a unique device identifier to perform de-duplication of hardware in the connections screen, and to work out which communications links belong to which devices.

Being able to distinguish between microcontrollers allows the connections screen UI to correctly show when a new device has been connected, or when a previously connected device is reconnected.

If your device doesn't support multiple communication links - the device ID functionality is not requried as the UI will derive a unique identifier from the USB enumeration strings.

Sources of Entropy

Obtaining a unique identifier for a microcontroller can be easy if your hardware supports some kind of persistent identifier. Examples include:

  • Hardware Secure ID chips connected to your microcontroller,
  • Microcontroller internal UUID, often integrating product family and batch codes,
  • MAC Addresses for WiFi or Bluetooth chipsets,
  • USB enumeration serial number (actually check this number changes per-device),
  • Unit specifc serial numbers or data burned into flash/EEPROM during manufacture,

Use of these properly unique strings is ideal where the chance of collisions is very low.

If such unique identifying information isn't available per-microcontroller and no non-volatile storage is available, there are a few potential methods of generating a temporary UUID:

  • Sample some non-deterministic information like ADC values, or from a hardware RNG peripheral
  • Use your sampled data as the seed for a software random number generator to reduce the chance of collisions - look at KISS (and the lighterweight variants) for a quick and well respected alternative to the oft-flawed stdlib rand().

Setting the device ID

Using electricui-embedded, call eui_setup_identifier( char * uuid, uint8_t bytes ), with a pointer to your UUID, and the length of the UUID.

Internally, the input uuid is hashed to fit the 16-bit internal UUID value.

As an example, using the 96-bit UUID integrated in the STM32F4 which is located at the address 0x1FFF7A10.

#define STM32_UUID ((uint32_t *)0x1FFF7A10)
eui_setup_identifier( (char *)STM32_UUID, 12 ); // 96-bit UUID is 12 bytes

Common mistake!

sizeof( STM32_UUID ) is not used for the length, as STM32_UUID is an address and would return 4-bytes.

As ST integrate the microcontroller's family and product line information, factory, wafer position and more into the UUID, the full 96-bits are needed.

Additional Identifying Fields

It is sensible to provide additional fields marking your device if you plan on supporting multiple products with the same UI, will have different feature sets, or different firmware builds in the field.

We recommend bundling this information into a custom type, with including example information such as:

  • Firmware version number,
  • Hardware identifier to distinguish different versions of your product running the same firmware,
  • Git branch, SHA and tag info if applicable,
  • Firmware build date, manufacture date, QA information,

For an example, bash or bat scripts can bundle git information into C header defines which is then referenced in firmware. Refer to the linked snippets and modify as required. We recommend running them as part of a pre-build phase during firmware build.

This information would be exposed to Electric UI like any other custom data.