Integration, resource assembly and source-SDK contract¶
Next-generation integration contract. See current delivery for implemented modes and actual acceptance.
tools/configure/and current public headers define exact schemas and APIs. Illustrative commands do not qualify three physical Boards or promise product releases.
This document explains integration of CPUs, SoCs, Boards, external devices, protocols and components, and how external projects produce reviewable firmware. See platform design for boundaries and engineering handbook for development, validation and maintenance.
Initial scope is STM32F407ZGT6 Qiming V3.1, STM32F407VET6 Sky Star Youth and GD32F470ZGT6 Liangshan Pi, with bare-metal and FreeRTOS backends. Hardware is not connected now. Source review, software implementation, compile/link results, model behavior and physical qualification are distinct. Actual PCB revisions, jumper settings, electrical facts and fitted parts remain unknown where unverified.
1. 第一原则与工具边界¶
Integration does not turn every hardware description into a runtime device tree. It submits bounded facts, selects maintained capabilities, checks resources and explicitly assembles static objects.
Use C11, CMake, Ninja, TOML assembly inputs, JSON hardware facts and a narrow Python validator/generator. The default core needs no heap, runtime string lookup, discovery or background workers.
The default input is the external project’s
assembly.toml. SoC, Board and assembly inputs are validated once into frozen typed IR;resolved.jsonis its authoritative JSON projection.CMake remains authoritative for code targets and dependencies. Generators produce no component dependency graph, business threads, product main or scheduling policy.
Instance selection uses TOML schema 2; SoC/Board facts remain JSON. Tools parse only that assembly input; Kconfig, CMake cache and old generated headers do not become parallel authorities.
Directories may follow
core/ arch/ soc/ io/ os/ components/ tools/ tests/; Boards may be separate packages. Layer names describe responsibility without requiring each layer, port or object to occupy a separate translation unit.Unmaintained capabilities do not become available merely because the SDK has a macro, a route table has an AF value or another family member has an example. Integrate new routes, DMA modes and controllers separately.
2. 各类接入拥有的事实¶
Category |
Owned facts and implementation |
Explicitly not owned |
|---|---|---|
CPU / Arch |
Instruction set, exception context, barriers, atomics/critical sections, FPU context and ABI conventions. |
Specific PCBs, controller IRQ/DMA assignments or product devices. |
SoC |
Exact part/package/density, memory domains, controllers, clock constraints, IRQ/EXTI, DMA, pin/AF routes, Flash geometry and private SDK. |
Board wiring, application roles or product partitions. |
Board |
PCB/source revisions, oscillators, electrical levels, fitted devices, connectors, jumper conditions, initial safe levels and reviewed wiring. |
Overriding chip density, selecting the primary sensor or creating business tasks. |
External device driver |
Device commands/registers, conversion algorithms, initialization order, timing requirements and error semantics. |
Default GPIOs, default bus numbers or product sampling policy. |
protocol core |
Frame formats, parsing/encoding, bounded state machines and protocol timing rules. |
Default UARTs, RS485 DE pins, threads or customer business logic. |
component |
Reusable algorithms/services, narrow ports, explicit capacity and execution context. |
Implicit workers, automatic dependency discovery or fixed product storage. |
product / application |
main, workers, application roles, private protocols, configuration policy, partitions and update/health/manufacturing policy. |
Making the shared platform depend on product source. |
SoC providers implement public I/O/core contracts and use Arch. Device drivers use narrow bus/GPIO/time ports; protocol cores depend on neither Board nor OS; component adapters connect I/O/OS. External assemblies wire implementations together. Declaring onboard devices does not make the Board the device-driver owner.
Vendor SDKs, kernel implementation headers and mutable controller state stay private; public interfaces do not expose their structures. Similar STM32/GD32 names do not prove register compatibility or direct driver reuse.
3. 三类输入及少量文件模板¶
SoC package¶
A maintained SoC package typically includes:
soc/<family>/
soc.json # 精确 SKU、内存、时钟与控制器事实
routes.json # 已复核路由及模式的有限 allowlist
CMakeLists.txt # 私有 SDK/provider 的显式目标依赖
private/ # 私有 SDK 接口与硬件实现
... # startup、controller、clock/IRQ、linker 实现
Family directories may share code, but soc.json defines STM32F407VET6, STM32F407ZGT6 and GD32F470ZGT6 separately. A family string cannot replace part, package, Flash, SRAM domains and IRQ tables. Adding a part does not establish support for every existing controller.
Each routes.json record binds at least exact SKU, controller, pin/AF, clock domain, IRQ, allowed transfer modes, DMA routes and sources. Shared records explicitly constrain applicable SKUs/packages. Source review and physical qualification use separate fields.
Board package¶
With an existing SoC implementation, a new Board normally needs only:
boards/<board-id>/
board.json # 实际晶振、接线、电气、revision、资料来源
README.md # 跳线/连接器与已知限制
board.c # 可选:特殊电源/复位/安全初值动作
Boards do not copy SDKs, HALs, RTOS ports or linker scripts. Ordinary GPIO initial levels and pin bindings are data. Add board.c only for bounded electrical actions not expressible through maintained data contracts; that code still uses neutral hardware ports.
The following fields are illustrative; example-board does not claim a real maintained Board:
{
"schema_version": 1,
"id": "example-board",
"soc": "STM32F407ZGT6",
"soc_family": "stm32f407",
"source_revision": "document-revision",
"physical_pcb_revision": null,
"clocks": {"hse_hz": 8000000},
"bindings": [],
"reserved_resources": [],
"unknowns": ["physical PCB identity and connector wiring pending"],
"provenance": []
}
Replace oscillator values with the Board’s source facts. Empty bindings provide no UART/SPI/I2C/RS485. Before adding real wiring, verify connectors, pins, levels, jumpers and reviewed SoC routes. Boards reference SoC memory facts rather than maintaining a drifting RAM/Flash copy.
External assembly¶
External nexus-examples or private products supply assembly.toml selecting Board packages, OS backends, clock profiles, resources and device instances. This minimal illustration declares no peripheral instances:
schema = 2
board_package = "./boards/example-board"
backend = "baremetal"
clock = "selected-profile-id"
[memory]
main_stack_bytes = 4096
libc_heap_bytes = 0
selected-profile-id is an illustrative placeholder; unknown profiles must fail. Category tables such as [uart.link0] select only Board-declared, SoC-maintained bindings with explicit polling/IRQ/DMA modes, required ring capacities and IRQ priorities. [spi_device.sensor0] and [i2c_device.sensor0] explicitly bind controllers and CS/address without workers. Factories return immutable controller and child faces separately.
Without an external product layout, images use only the maintained full physical Flash default layout. The platform reserves no generic product storage. Selected product layouts become complete declared assembly inputs and enter resolved IR through the same path.
4. 解析、生成与 CMake 装配¶
Configuration must follow this fixed order:
Read the assembly, locate one Board and its exact SoC part, then check schemas, versions and dependency locks.
Check package containment, declared inputs and known/unknown source conditions; expand selected bindings and devices.
Build resource claims; check mode capabilities, conflicts, clocks, IRQs, memory, ABI and layout.
Atomically write one
resolved.jsonrecording decisions, rejections and input digests.Derive hardware headers, read-only resource tables and linker inputs from IR; CMake reads necessary selections and builds its declared dependencies.
Verify vectors, startup, handlers, region capacities and artifact identity in actual ELF/map/BIN outputs. Results become evidence without posing as hardware qualification.
resolved.json retains schema, packages/parts/backends, effective options, clock/memory/ABI, resource claims, devices, limitations and input hashes. It is neither a CMake dependency graph nor guessed business threads, roles or domain policy.
All derived outputs come from that IR. No .config, old headers or separate Board default macros become fallback authorities. Failed generation invalidates configuration; never consume the prior bundle. Write to a temporary directory and switch only after complete success. Separate Board/backend/profile combinations use separate roots.
Each CMake library declares code dependencies, public headers and private SDK compile surfaces explicitly. Assembly selects hardware instances/modes without replacing target_link_libraries(). Generators neither infer component needs from arbitrary business source nor link all drivers. Target capability requirements contradicting resolved configuration must fail.
Tools may generate static descriptors; mutable contexts and actual construction/init still have explicit implementation owners. Product main owns component/device initialization order and scheduler start. A device node does not create a sampling task.
5. 资源占用与编译前检查¶
Resource |
Required checks |
|---|---|
pin |
The exact package has the pin; routes are allowlisted and reviewed; AF/direction/electrical constraints hold; SWD, onboard devices and selected functions do not conflict. |
controller |
The provider implements the selected mode; one owner holds the physical controller; shared-bus children derive from that owner. |
SPI child |
Separate CS lines; mode, frequency and word width must fit maintained configurations; explicit serialized arbitration. |
I2C child |
Legal addresses/mux levels; conflicting addresses rejected; controller and mux modes both implemented. |
DMA |
Validate the actual DMA controller/stream/channel/request model, legal routes, exclusive-resource conflicts and implemented modes. |
IRQ |
Each vector has one provider or explicit bounded dispatcher; priority, grouping and kernel-call permissions agree. |
EXTI |
Check exclusive line/port muxing, edges, shared vectors, event capacity and priority rather than only pin names. |
timer/PWM |
Check timer/channel, timebase, shared PSC/ARR/base mode and triggers. Channels on one timer are not independent timebases. |
ADC |
Check channels, sampling time, sequences, triggers, reference-voltage conditions and exact sampling modes; maintain DMA/stream separately. |
watchdog |
Check maintained IWDG range, LSI error and irreversible enabling. Feeding/health policy remains external. |
clock |
Oscillators, PLLs, buses, Flash wait states, peripheral frequencies and backend timebase meet maintained profiles. |
memory |
Exact physical domains, DMA reachability, alignment, stack/pool/queue budgets, layout/erase boundaries and image capacity. |
ABI |
Consistent CPU/Thumb/FPU/float ABI, correct FreeRTOS port and exact-part macros from resolved configuration. |
Resource claims must identify physical resource keys, owners, modes and origins. Diagnostics say “DMA1 stream X is claimed by A and B”, not merely “invalid configuration”. Tools validate explicit choices without finding alternate streams, changing pins or lowering clocks.
Sharing SPI/I2C buses does not mean declaring controllers twice. One provider manages the bus; children retain bounded references. Duplicate SPI CS or same-level I2C addresses fail. Direct single-executor calls and explicit queue/service adapters are distinct: only the adapter executor advances shared controllers; waiting clients do not take over. Short locks protect admission/control metadata, never hold task mutexes across DMA lifetimes. Device drivers do not implicitly require kernel locks.
Real shared IRQs may use SoC-declared static dispatchers with checked handler lists and bounded execution. Two strong symbols cannot compete for one vector; arbitrary runtime registration is excluded. IRQ response/settlement and subsequent task/worker processing have separate owners.
FreeRTOS reserves port resources including SysTick/PendSV/SVC. Configure priority grouping consistently; kernel-calling ISRs must meet the port’s syscall-priority rules, while higher-priority ISRs cannot use those OS APIs. Alternate timer timebases enter the same claims table.
Specific clock, memory and ABI boundaries¶
Boards supply actual HSE/LSE, electrical and jumper facts; SoCs supply legal constraints and maintained profiles; assemblies choose profiles. Controllers do not reconfigure global clocks independently; drivers do not reset NVIC grouping. Without implemented dynamic-clock switching, runtime switch requests return unsupported.
Declare each SRAM domain’s address, size, initialization, DMA reachability and usage restrictions separately. STM32 CCM is not default DMA SRAM; all physical SRAM cannot become one unmaintained linker heap. Initially enable only implemented, checked domains; others remain unmaintained.
Linker sections, alignment and maps validate static DMA buffers; runtime validation still checks caller-provided pointers for reachability/alignment. Compile checks cannot replace borrowing/settlement lifetimes. Budgets distinguish MSP, task stacks, OS objects, I/O buffers, component workspaces and optional libc heaps.
Flash layouts use exact-part erase geometry and reject out-of-range, overlapping or erase-misaligned regions. Image offsets, VTOR and bootloader/A-B require maintained implementations together; changing link addresses alone does not establish support.
CPU flags, FPU enabling, exception contexts and kernel ports must agree. Record toolchain and all precompiled-input ABIs in identity. Source SDKs are recommended; installed-binary ABI compatibility across compilers/versions/flags is not promised by default.
What each stage can establish¶
Pregeneration validates fact consistency and conflicts. C11 _Static_assert and types establish capacity/type/constant relationships. Linker/map/ELF checks establish layouts, symbols, handlers and retention. Waveforms, electrical levels, clock error, IRQ latency, DMA terminal states and sustained loads need physical evidence.
6. 实例名、应用 role 与静态成本¶
USART1 names a SoC controller; j1_uart and bme280_ext0 are stable assembly instance names; console and ambient_sensor are external application roles. Boards supply physical resources without selecting the product’s primary sensor.
External consumers own role mappings/constraints. Their build steps may read resolved information, validate required interfaces and generate typed aliases/accessors. The platform generates no product role policy. After rebinding hardware, applications still use roles rather than searching business source for UART/GPIO numbers.
Ordinary data paths need no runtime string lookup. Read-only wiring resides in Flash; required contexts, pools, queues and buffers are static. Role aliases can compile to direct symbols; generic drivers retain one function-pointer layer only where narrow ports require it. Layer names do not justify extra objects or virtual calls.
Implemented static instances and typed factories¶
Factories preserve the typed polymorphic-interface architecture. Generators create static objects; factories return existing identities without creating, initializing, locking or reconfiguring devices. Typed getters include nx_factory_uart(nx_uart_id_t). IDs are uint16_t with named constants; out-of-range, COUNT and unselected categories return NULL. IDs are assembly-local, not persistent formats or cross-version binary ABIs.
Each public face is read-only { const ops*, void* context }: two pointers on 32-bit targets, with actual Flash/RAM audited from linked outputs. Each provider/mode shares const ops; mutable state and exact-capacity arrays are separate. Methods receive instance context, never treating shared ops as an instance. IRQs statically enter providers without per-byte virtual dispatch. Native instances also have separate generated state; singleton fixtures are explicitly test-only.
Object |
Implemented static generation responsibility |
|---|---|
controller port |
One necessary exclusive-controller state and one read-only public face. |
GPIO view |
Separate authorized masks/directions; validate different pins sharing the GPIO base independently. |
bus endpoint |
Each SPI CS or I2C address has its own face/private configuration, without borrowing the first device’s identity. |
mode storage |
Allocate only selected UART/EXTI profiles, capacities and explicit Native register models. |
typed factory |
Pure static switch; no registration, string lookup, heap or hidden workers. |
ops |
Instances of the same provider/mode share a read-only table; different implementations keep the same public interface layout. |
IRQ wiring |
Fixed instances dispatch directly; genuinely shared EXTI uses bounded static dispatchers. |
startup |
Explicit serial calls and reverse cleanup; BUSY retains progress and all borrowed storage. |
component |
External composition provides storage, narrow ports and scheduling without generated business instances. |
nx_binding_<bus> and nx_factory_spi/i2c return actual controller ports; nx_device_<child> and nx_factory_spi_device/i2c_device return endpoints. Public I2C recovery therefore always has bus identity. Applications cannot treat bus aliases as the first endpoint. Polling and asynchronous modes implement resources/capabilities separately; getters never switch modes implicitly.
Assemblies use TOML schema 2; one authored.py field model provides strict parsing and editor schemas. Frozen ControllerIR/EndpointIR/MemoryBudgetIR/ConfigurationIR feeds emitters directly; resolved.json serializes the decisions. configure.py init/list-bindings/check/explain/generate share the resolver. CMake adds exact reconfiguration dependencies from resolver input paths without reparsing TOML.
STM32 USART1 dma-tx uses fixed DMA2 stream7 channel4; RX retains its separate IRQ ring. DMA domains/runtime pointer validation, memory-engine detach and UART TC wire draining are verified separately; NDTR=0 is not UART completion. Different selectors for one physical stream still conflict. Other DMA/stream modes claim support only within their own code/model/link/physical evidence.
Obtaining a static face neither changes startup state nor grants concurrent execution rights. Cancel, timeout, stop and restart cannot revoke request borrows early; only acquire-observed SETTLED permits reclamation. Explicit owner executors advance shared paths; products own tasks and recovery policy.
Source SDKs contain public interfaces, strict configuration tools and exact dependency identities. Code/comments preserve current style. Behavior changes use failing-tests-first TDD; host GoogleTest/GoogleMock links separately from production C11 drivers. Ordinary SDK firmware contains no testing framework.
7. 新 Board 接入流程¶
Collect exact MCU, PCB/document revisions, schematic/BOM sources, oscillators, supplies, SWD, connectors, jumpers and default levels. Unknown actual PCB revisions remain null.
Confirm maintained SoC implementation and select minimal resources, such as an LED and UART. Review each route without assuming all connectors are supported.
Write
board.jsonand README; add neutral Board hooks only for special power/reset actions. Identify reviewed sources and unexecuted physical items.Create an external
assembly.tomland explicit main; begin with bare metal and build actual ARM ELF/map/BIN. Check resource plans, clocks, memory, ABI, vectors and handlers.Create a FreeRTOS assembly for those resources and check port, timebase, IRQ priority and static budgets. Use separate roots for both backends.
Record exact tuples and actual software evidence. Without hardware, physical initialization, electrical behavior, IRQ/DMA and long runs remain not executed.
Individually establish maintained MCU I2C/SPI routes/modes and RS485 transceiver/DE/RE wiring on all three initial Boards. Names do not establish availability. This proposal does not automatically remove Qiming’s disabled SPI, unverified RS485 conditions or missing actual PCB revision.
8. 新 SoC 或精确 SKU 接入流程¶
Distinguish new packages/densities from new register/clock/IRQ/DMA implementations rather than classifying solely by marketing family.
Pin official documents, errata, SDK revisions, licenses and import hashes; record exact part/package/density.
Define physical memory, Flash geometry, clock constraints, IRQs and controllers in
soc.json. Initially include only reviewed routes intended for maintenance.Implement required Arch adapters, reset/startup, clocks, timebase, IRQs, linker and minimum I/O providers. SDK targets stay PRIVATE; no vendor structures leak to consumers.
Start with minimal ELF link fixtures, then compile/link actual bare-metal and FreeRTOS ports/configurations. Establish necessary model evidence for behavioral error, terminal-resource and cancellation paths.
Expand matrices separately for new controllers/routes/DMA modes. SDK features without providers do not become selectable maintained capabilities.
Without physical qualification, delivery reaches only executed software items. Related-chip results do not confer physical support.
9. 新外部器件 driver 接入流程¶
Consider a BME280 SPI driver; this example does not claim reviewed SPI wiring on the three initial Boards.
Confirm reviewed SPI bindings, CS and electrical conditions. Otherwise first integrate SoC routes/controllers and Board wiring independently.
Create device-core public headers, implementation and CMake; define bounded contexts and narrow transaction/time ports. Drivers own registers, chip-ID, calibration parsing and conversion algorithms.
Declare required bus modes/word widths/frequencies, initialization timing, ISR/task restrictions, timeout origins, buffer borrows, post-failure states and recovery conditions.
External assemblies create
bme280_ext0with bus child/CS and fixed capacities; CMake explicitly links drivers and adapters.Consumers map
ambient_sensorthemselves. Bare-metal main calls periodically; FreeRTOS product workers call the same driver. The platform creates no automatic task.Fake ports verify parsing, error responses, deadlines and ownership. Actual ARM links verify interfaces, capacity and assembly. Chip-ID checks belong to instance initialization, not device scanning.
Qualify real wiring, waveforms, sensor error and sustained loads separately. Without hardware, record only executed software evidence.
Device drivers do not automatically make Flash-bus storage product Storage or reserve product regions. W25Q, for example, needs actual fitted-part, capacity, erase-geometry facts and external layout policy.
10. 新 protocol / component 接入流程¶
Establish reuse value and platform-maintenance worth. Customer-private protocols, product flows and domain control stay external.
Define Board/SDK-independent cores with fixed maximum frame lengths, node counts, workspaces and failure semantics. Parsers must not implicitly open UARTs or create tasks.
Connect through narrow transport/time/storage ports with separately optional adapters; CMake declares code dependencies explicitly.
External assemblies select only transport hardware resources; products explicitly configure protocol roles, scheduling and workers.
Verify observable protocol behavior, invalid inputs, boundaries and exhaustion, and link actual firmware. Electrical and frame-timing qualification still needs physical evidence.
RS485 needs Board/external wiring facts for transceivers, levels, DE/RE, isolation and termination. SoC UART providers own maintained transfer terminal states; protocols/adapters define direction-switch timing. Software delays or generic UART success cannot replace actual TC and line qualification.
11. 外部源码 SDK 消费与升级¶
An external project normally needs only:
nexus-examples/<application>/
CMakeLists.txt
CMakePresets.json
assembly.toml
dependencies.lock.json
main.c
... # 产品自己的 role、worker、layout 和策略
Pin source SDK/commit and dependency locks, verify packages, integrate through public CMake entry points, then explicitly link platform capabilities/components. CMake presets select toolchains/build modes; assemblies select hardware/backends. Their responsibilities do not overlap.
SDK preparation/consumption requires complete source with pinned dependencies. Missing submodules or snapshots are not silently releasable SDKs. Packages include manifests, licenses, relative CMake configurations and input identities, followed by actual consumer verification after relocation. Relocatability does not prove ABI compatibility.
Upgrade PRs change platform pins, callers and necessary assemblies/schemas together. Breaking contracts specify versions and migration instructions, then rerun exact support-tuple software regressions. Old-source/configuration results do not qualify new inputs. Product promotion uses reviewed identical artifact digests without silent rebuilding.
External products own bootloaders, A/B, signing, rollback, manufacturing and field updates. Layout, image-offset and persistent-format changes need product migration/recovery contracts and qualification; source-SDK upgrades do not do that work automatically.
12. 版本、路径、摘要与产物身份¶
SoC/Board/assembly/resolved inputs have explicit schema versions. Reject unknown versions/fields and contradictions rather than silently ignoring them. Necessary extensions use controlled namespaces without hiding effective compile options.
Packages record API/contract versions, exact dependency revisions and origins. Schema compatibility does not establish hardware or behavioral compatibility.
Relative paths are anchored to their owning manifests. Board source stays inside its package; reject
.., symlink escapes and undeclared source. SDK paths must not inherit consumer-ancestor Git identity accidentally.Declare and hash all build-affecting inputs: routes, Board hooks, layouts, vendor imports, dependency locks, toolchains and compile options. Raw-byte hashes identify inputs; normalized resolved JSON identifies effective configuration. Algorithms/formats are versioned.
Do not update dependencies over the network secretly during resolution/build. New effective sources not declared in manifests must fail or be added explicitly; directory additions cannot bypass identity checks.
Product and platform identities are separate. Platforms supply neutral part/Board/configuration facts without owning product names, SKUs or manufacturing policy.
Artifact manifests bind platform/consumer revisions, dependencies, toolchains, SoC/Board/assembly/resolved/layout hashes, ELF/BIN/map digests and evidence scope.
Dirty development builds may be explicitly allowed but are marked
publishable=false. Missing inputs, hash mismatches, stale evidence and snapshots cannot gain release qualification.
13. 支持 tuple 与支持等级¶
The minimum support unit is:
<platform source, consumer source, exact MCU part/package,
Board source revision, physical PCB revision or unknown,
route, transfer mode, OS backend, resolved config hash,
toolchain/ABI, layout hash>
Board names are lookup aids, not promises for all onboard peripherals. UART IRQ tuple results do not qualify SPI DMA, I2C, RS485 or another backend on that Board.
Record |
Established scope |
Not established |
|---|---|---|
D: description review |
Part, wiring and routes reviewed in named source documents. |
Actual fitted parts, PCBs or usable wiring. |
C: compile/link |
Actual ARM ELF, layout and assembly pass with the specified toolchain. |
Hardware execution or correct timing. |
M: model behavior |
Host/fake behavior passes for exact source/configuration. |
Electrical behavior or actual IRQ/DMA terminal states. |
H: physical paths |
Actual measurements for exact PCB, route and mode. |
Arbitrary loads, other peripherals or complete-product qualification. |
Q: product workload qualification |
Acceptance under named workloads, budgets and product policy. |
Other products, unlimited support windows or LTS. |
These are separate evidence dimensions, not one hierarchy letting models replace compilation/hardware. Missing C/M/H/Q evidence is explicitly not executed. Logs, artifacts, source/configuration and budgets bind the same tuple.
The first stage may establish six base software combinations: three Boards × two backends. Each claims only paths actually selected and executed. Expand I2C/SPI/RS485/DMA columns by maintained facts. Without hardware, H/Q remain empty; role lists, workflows and fixtures do not fill that gap.
With ten people and 3–6 months, prioritize narrow schemas, six base firmware combinations, needed controllers/drivers and reviewable artifacts. Complete pin databases, all SDK features, automatic topology solving and runtime discovery are not first-stage exit criteria.