H753_CPP_Device_Electronic_Signature 1.0
STM32H753 96-bit device unique ID read and print tutorial
Loading...
Searching...
No Matches
H753 Device Electronic Signature

A bare-metal (no RTOS) firmware for an STM32H753ZI that reads ST's "device electronic signature" – the factory-programmed 96-bit unique device ID, the DBGMCU device/revision ID, and the flash capacity register – and prints all of it over the standard debug USART. It is a from-scratch revision of the site's older STM32 Unique ID tutorial, simplified and modernized.

Status: hardware-validated. Confirmed on real hardware (Nucleo-H753ZI): prints the UID, device/revision ID, and flash capacity correctly over the FTDI debug UART.

How it works

After clock and peripheral init, the firmware reads and prints three separate pieces of factory-programmed identification data:

  1. The 96-bit unique device ID (HAL_GetUIDw0/1/2()) – unique per chip.
  2. DBGMCU->IDCODE – device ID (identical for every STM32H753ZI) and revision ID (can vary by silicon manufacturing batch).
  3. The flash capacity register at FLASHSIZE_BASE – this part's flash size in Kbytes.

No hashing, no packing into a derived value – the raw data is printed as-is. See Core/Src/main.c for the full explanation of why, including a discussion of the UID's own internal structure (wafer coordinates and an ASCII-encoded lot number, per ST's reference manual) and a worked example of using the UID to select a board's role (TX vs. RX) from a single shared firmware image, contrasted against the #ifdef-based compile-time alternative.

Hardware

Peripheral Interface Pins Notes
Debug console USART1 PA9 (TX) / PA10 (RX) 19200 baud, 8N1, via external FTDI adapter (not the onboard ST-LINK VCP)

MCU: STM32H753ZITx (LQFP144). No other circuitry is required – every register this project reads is internal to the MCU.

Relationship to the older tutorial

The original STM32 Unique ID tutorial (F103_C_Device_Electronic_Signature, 2024) additionally ran the UID through a third-party 32-bit hash function (Hash32Len5to12() from a borrowed stm32_uidhash.h), had a real bug in that step (it hashed the wrong variable), and never printed any result over serial at all. This revision drops the hash entirely – direct comparison of the raw UID words is sufficient for identifying a specific board, as demonstrated in the F439_CPP_TX-RX_LoRa_Project_01 project's RX/TX role selection – adds real USART output, and additionally reads the device/revision ID and flash size registers the original never touched.

Board independence

The register reads here are identical on every STM32 board regardless of family or package – HAL_GetUIDw0/1/2(), DBGMCU->IDCODE, and FLASHSIZE_BASE are all internal MCU registers with no external wiring involved. The Nucleo-H753ZI used here is purely a build convenience (reusing an already-proven USART1/FTDI setup), not a requirement.

Firmware architecture

No RTOS – a single superloop in Core/Src/main.c. Unlike the site's driver-class-based projects (e.g. the W25Q flash tutorials), this project doesn't have a dedicated driver class: reading three fixed registers and printing them is small enough that a class would be pure overhead, not a simplification.

Building

This is an STM32CubeIDE project, but it can also be built headlessly from the command line using CubeIDE's bundled ARM GCC toolchain:

cd Debug
TOOLCHAIN_BIN="/opt/st/stm32cubeide_1.18.1/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.13.3.rel1.linux64_1.0.0.202410170706/tools/bin"
export PATH="$TOOLCHAIN_BIN:$PATH"
make -j4 all

This produces H753_CPP_Device_Electronic_Signature.elf. Grep the make output for warning:/error: to check a change compiles cleanly.

Debug output

Captured from a real run over the FTDI debug UART:

=== STM32H753ZI Device Electronic Signature ===
Unique Device ID (96-bit, factory-programmed, unique per chip):
Word 0 : 0x001F0022
Word 1 : 0x32335101
Word 2 : 0x34343734
Device Identification (DBGMCU->IDCODE -- board-independent):
Device ID : 0x450 (same for every H753ZI)
Revision ID : 0x2003 (silicon revision -- can vary by mfg batch)
Flash Capacity (FLASHSIZE_BASE):
2048 Kbytes

Documentation

Doxygen-generated documentation covers main.c's register reads and the TX/RX role-selection discussion. Generate it locally with doxygen Doxyfile.

Contributing

No direct commits to master – branch, open a PR, and merge. This project has been confirmed working on real hardware.