STM32G474RET6 / MB1367 initial vertical slice

This is a source-reviewed STM32G474RET6 baseline for NUCLEO-G474RE. It implements CPU startup, a fixed clock transaction, TIM2 time, GPIOA, LPUART1 IRQ bytes and independent PA0/PA1 EXTI edge events. It does not establish Flash programming, DMA, ADC, SPI, I2C, FDCAN, USB, Ethernet, low-power continuity or other G4 peripheral support. Unsupported modes must fail the configuration resolver. Actual PCB inspection and all HIL remain not executed.

Reviewed sources

Source

Revision / pinned identity

Relevant facts

STM32G474xx datasheet

DS12288 Rev6

M4F, 170 MHz, memory and clock limits

STM32G4 reference manual

RM0440 Rev9

RCC/PWR/Flash boost sequence, TIM2, GPIO, LPUART

MB1367 user manual

UM2505 Rev7

X3, VCP bridges and LD2 wiring

CMSIS Device G4

626ee412334a5ed2e5b320af5a8d77d69f03a558

Actual G474 register masks/layout, IRQ102, GCC startup

Source hashes and original SDK licensing belong in the dependency lock and review evidence. Vendor notices and LICENSE.md remain unchanged. The public Nexus interface stays independent of register definitions.

Exact target and memory

The initial target is STM32G474RET6, Cortex-M4F, ARMv7E-M, FPv4-SP-D16 hard ABI, DSP and DWT CYCCNT. External IRQ IDs cover 0..101, including TIM2=28, LPUART1=91 and FMAC=101. Four priority bits are implemented.

Flash is 512 KiB at 0x08000000. Startup checks observed DEV_ID 0x469, Flash density 512 KiB and actual DBANK=1. DEV_ID identifies a silicon category, not the package or order code. DBANK=1 yields 2 KiB pages across two banks; DBANK=0 is rejected by this first geometry profile. Startup never writes option bytes or performs erase or programming. A product must verify the exact order code and option state.

RAM consists of 80 KiB SRAM1 at 0x20000000, 16 KiB SRAM2 at 0x20014000, and 32 KiB CCM with a system-bus alias at 0x20018000. The CCM CPU address 0x10000000 aliases the same physical storage and is not counted again. The first linker layout uses one contiguous 128 KiB region at 0x20000000 and reserves 2048 bytes for MSP. This CPU-only layout makes no implemented DMA-provider claim. No caller buffer is silently relocated into another memory region.

Reference Board facts and uncertainty

Function

Reviewed default reference

Required physical confirmation

HSE

X3 24 MHz crystal, SB25/SB26 on, SB27 off

Fitted X3 and actual bridge/revision

LED LD2

PA5, active high, SB6 on

LED and bridge population

ST-LINK VCP

LPUART1 PA2 TX / PA3 RX, AF12; SB17/SB23 on, SB18/SB22/SB13/SB19 off

Actual bridge and ST-LINK connection

The alternate ST-LINK MCO 8 MHz clock wiring needs a different reviewed profile and is not accepted here. The VCP route is LPUART1, not USART2. Source review does not prove physical electrical states, UART reception, board power or oscillator frequency. Private PCB data and bridge policy stay outside the platform.

Clock transaction and rollback

Admission requires privileged task context, incoming masks clear, positive phase poll budget, reset-like HSI16 selected, PLL/HSE idle and reserved TIM2/NVIC unused. Unknown active resources are rejected before effects. A poll count bounds work; it is not an elapsed-time deadline while the timebase is unavailable.

The reviewed profile is HSE 24 / PLLM 6 / PLLN 85 / PLLR 2 = 170 MHz. PLL input is 4 MHz and VCO 340 MHz, inside the datasheet limits. HCLK/APB1/APB2 and the TIM2 kernel clock are 170 MHz. G4 uses SW_HSI=1 and SW_PLL=3; F4 clock encodings are not reused.

Startup acquires PWREN with readback and a barrier before reading PWR state. It selects voltage range 1, waits for VOSF clear, uses boost mode and four Flash wait states, starts and observes HSE/PLL, switches through AHB/2 (85 MHz), waits at least the required transition interval, then selects AHB/1. The actual M4 object contains 85 dependent SUBS/BNE iterations at verified 85 MHz. At least 170 instructions/core cycles gives a conservative 2 microsecond lower bound; IRQs can extend it. Physical timing remains unmeasured. Volatile accesses, readback and ordering barriers cannot be optimized away.

Failure records the primary result, cleanup result and still-owned effects. Rollback restores observed HSI before disabling PLL/HSE or reducing Flash/voltage settings. TIM2 source withdrawal and NVIC proof precede removing its ownership. Failed rollback retains the resource bits for explicit retry; it never reports successful cleanup or publishes usable I/O. Stop requires every external peripheral/task consumer already joined; no hidden coordinator guesses this.

Time, GPIO and serial contracts

TIM2 is reserved: 32-bit count, prescaler 169, ARR 0xffffffff, 1 MHz, overflow IRQ priority0 with no OS API. Snapshot saves/restores interrupt state and corrects one pending overflow; IRQ must run at least once per 2^32 microseconds. NMI, HardFault, dynamic reclocking and deep sleep are outside this time contract.

GPIO initialization preloads BSRR and observes ODR before exposing a mode. It observes push/pull and pull configuration, then the selected MODER bits. Partial failure retains the instance for an explicit inactive-level rollback. Hot writes use BSRR directly. Toggle requires the single-owner serialization contract.

LPUART1 supports caller-owned byte rings and one borrowed TX request. Its actual 20-bit BRR is round(256PCLK/(16baud)), range0x300..0xfffff; 115200 at 170 MHz uses PRESC=16 (register7), BRR 23611. Initialization observes TEACK/REACK before publishing the face. IRQ is bounded to one TX byte and one RX byte, reports aggregate corruption/overflow loss and preserves older ring contents. It does not reuse F4’s USART divisor, register offsets or error-clear sequences.

TXE proves a register can accept a byte; TC proves the final wire byte completed. Request metadata/payload/ring/private registers/wake target cannot overlap. Cancel and timeout disable new sends, then wait for actual wire completion. Failed drain retains QUARANTINED storage; later hardware proof can settle it. The provider detaches its active pointer and interrupt sources before SETTLED, which is its final request access. Cold stop closes admission, joins captured callbacks, observes UE and TEACK/REACK off, disables/clears/readbacks NVIC, then withdraws ring/wake ownership. FreeRTOS-capable sinks require actual priority and priority-group validation; waking does not start a scheduler.

Software evidence and outstanding qualification

Exact EXTI extension

EXTI0/PA0 and EXTI1/PA1 use independent IRQ6/7 with explicit priority and caller-selected 1..4096 event slots. RM0440 Rev9 section10.2.3 pp367–368 gives the GPIOA zero encoding of each SYSCFG_EXTICR1 field; sections15.3–15.5 pp441–453 describe interrupt selection and W1C EXTI_PR1. The official CMSIS layout and exact-part package inventory supply the register and pin facts. tests/contracts/g474_assembly/exti_board is only a software fixture; it does not assert an actual NUCLEO button, connector, bias resistor or electrical route.

The common edge-event face has a single task reader and one IRQ producer per line. Each invocation acknowledges one selected pending bit, samples at most one level and records one timebase timestamp. Hardware edges may coalesce; both-edge direction reflects the sampled level. No polling loop reconstructs lost edges. A full ring preserves older events, exposes a separate loss boundary and only then admits later events. CPU exclusion per copied event is bounded; read work scales with the explicit caller capacity.

Platform admission checks line masks, triggers, pending and NVIC before changing global clocks or GPIO. A shared SYSCFG gate has one generated owner and retains a preexisting enable. Each line saves its mux nibble and restores only that field after its own sources and independent vector are observed withdrawn. GPIO cold leases restore the original input/analog state at complete Platform stop. A failed cleanup keeps storage and recovery responsibility. Wake binding checks actual IRQ policy and joins captured callbacks before releasing storage. No public API, dynamic allocation, worker, runtime registry or extra OS layer is introduced.

The two authored EXTI fixtures select baremetal/FreeRTOS and exact three/two event capacities. Native GoogleTest/GoogleMock executes the real provider and generated two-line factory; ARM fixtures retain the selected ops/handlers and actual FreeRTOS graph. Empty and existing GPIO/LPUART fixtures remain separate regressions. Physical HIL remains not_executed: a future admitted station must confirm PA0/PA1 accessibility and bias, inject observed edges, compare instrument counts/waveforms with coalesced/loss semantics, measure IRQ latency and prove source withdrawal before storage reuse. Software success is not that evidence.

Existing baseline evidence

Actual host models execute the production register algorithm with official SDK layout and masks. They verify bounded timeout, failed rollback, initial-latch failure, source withdrawal, request alias rejection, wire drain, overflow, callback borrow and independent state. They do not establish oscillator, voltage, timing, peripheral errata or physical IRQ behavior.

An actual ARM C11 build with GCC 14.3 and the pinned official GCC startup links empty, LED, UART and mixed bare-metal ELFs. The selected types occupy System 56, GPIO 12, UART 72 and TX request 32 bytes. The small profile costs are measured from those ELF files and include the 2048-byte MSP reservation; they are not inferred from host sizeof. Unselected GPIO/UART symbols disappear through section GC.

Generated typed factories, both OS backend compositions, clean reproducible builds, exact SDK lock/bundle identities and any later Board HIL have separate qualification exits. Software-only delivery must keep physical status unknown.