AI Skill Report Card
Migrating SDK and Board Platforms
Quick Start14 / 15
Given a migration task (e.g., "migrate from Board A + SDK v1 to Board B + SDK v2"):
- Read vendor release notes + migration guide first — never guess API changes
- Build a dependency/API mapping table before touching code
- Start from a clean base project (vendor-provided skeleton, not a copy of old project)
- Migrate file-by-file, compiling incrementally
- Full build → flash to target → runtime verification
Recommendation▾
Add a concrete input/output example showing actual compiler error messages and how the mapping table resolves them
Workflow15 / 15
Progress:
- [ ] Step 1: Gather vendor release notes, migration guides, changelogs
- [ ] Step 2: Diff old vs new SDK — identify breaking changes
- [ ] Step 3: Inventory dependencies (include paths, preprocessor directives, linker scripts, build flags)
- [ ] Step 4: Build API mapping table (old API -> new API, behavior deltas)
- [ ] Step 5: Set up clean base project from new vendor SDK template
- [ ] Step 6: Migrate files incrementally, compiling after each
- [ ] Step 7: Resolve compile errors using the API mapping table
- [ ] Step 8: Full compilation success
- [ ] Step 9: Flash/program to target board
- [ ] Step 10: Runtime verification — confirm no crashes/faults/regressions
Step 1: Vendor Documentation Review
- Collect: release notes, migration guide, API reference diffs, errata sheets
- Note deprecated APIs, renamed functions, changed function signatures, removed headers
- Flag any behavioral changes (not just signature changes) — e.g., blocking vs non-blocking, default clock speeds, pin mux changes
Step 2: Dependency Inventory
Catalog what the old project relies on:
- Include paths (
-Iflags, header search paths) - Preprocessor directives (
#define, conditional compilation like#ifdef BOARD_X) - Linker scripts / memory maps
- Build system specifics (Makefile, CMakeLists, IDE project files)
- Third-party libraries pinned to old SDK
Step 3: API Mapping Table
Build a table before writing code:
| Old API/Symbol | New API/Symbol | Notes |
|---|---|---|
HAL_UART_Init() | UART_Init() | signature changed: timeout param removed |
BOARD_PIN_LED | BSP_LED_PIN | renamed macro |
#ifdef STM32F4 | #ifdef TARGET_MCU_F7 | board-specific guard swap |
Include "no direct equivalent" entries — these need custom shims or redesign.
Step 4: Base Project Setup
- Start from vendor's reference/example project for the new board/SDK, not a hacked copy of the old project
- Confirm this base project compiles and flashes successfully before adding any migrated code — this isolates environment issues from migration issues
Step 5: Incremental File Migration
- Migrate one file or module at a time, in dependency order (leaf utilities first, then drivers, then application logic)
- Compile after every file — don't batch many files before the first build attempt
- Keep old file as reference open side-by-side; don't delete until new version compiles and is verified
Step 6: Compile & Fix
- Resolve errors using the API mapping table first; only improvise when mapping has no entry
- Watch for silent issues compilers won't flag: changed default values, different struct padding, altered interrupt priority schemes
Step 7: Flash & Runtime Verification
- Program to target board
- Verify: boot sequence, peripheral init (UART/SPI/I2C/GPIO), no hard faults, no watchdog resets
- Compare runtime behavior against old board/SDK baseline if possible (same test cases, same expected outputs)
Recommendation▾
Include a template/checklist for the dependency inventory itself (not just the mapping table) to make Step 2 more actionable
Examples16 / 20
Example 1: Input: Migrate STM32F4 project using HAL v1.x to STM32F7 using HAL v2.x Output:
- Mapping table shows
HAL_UART_Initsignature changed,SystemClock_Configmust be regenerated for F7 clock tree,#ifdef STM32F4xx→#ifdef STM32F7xx - Base project: start from STM32CubeF7 example for the matching Nucleo/Discovery board
- Migrate in order: clock config → GPIO/BSP → peripheral drivers (UART/SPI) → middleware → application
- Compile after clock config alone, then after GPIO, etc.
- Flash, confirm UART prints boot message, no HardFault on peripheral init
Example 2: Input: Migrate from vendor SDK v2 to v3 on the same board (no hardware change) Output:
- Release notes show v3 renamed all
xxx_drv_prefixes toxxx_and removed deprecated blocking APIs - Dependency inventory shows build system changed CMake minimum version requirement
- Mapping table is mostly 1:1 renames plus a few API removals requiring rewritten calling code using interrupt/callback pattern
- Base project: regenerate from vendor's SDK v3 config tool rather than hand-editing old CMakeLists
- Migrate file by file, verify no regression in sensor polling rate at runtime
Recommendation▾
Consider adding a brief troubleshooting section for when runtime verification fails post-compile (e.g., debugging hard faults)
Best Practices
- Never skip reading official migration guide even if changes seem "obvious" from diffing headers — vendors often document non-obvious behavioral changes
- Always start from a known-good base project for the new target; don't mutate the old project in place
- Compile frequently (every file) rather than batching — isolates root cause immediately
- Keep a running mapping table as a living document; reuse it for future migrations on the same vendor family
- Treat successful compilation as necessary but not sufficient — always do runtime verification on real hardware
- When no direct API equivalent exists, write a thin shim/wrapper rather than scattering workarounds through application code
Common Pitfalls
- Assuming API rename = identical behavior (timing, blocking semantics, return codes may differ)
- Copying old project and find-replacing include paths instead of starting from vendor base project — hides subtle config/linker issues
- Migrating many files before first compile attempt — makes error triage painful
- Skipping preprocessor directive audit — stale
#ifdef OLD_BOARDblocks silently compile dead/wrong code - Declaring success at "it compiles" without flashing and testing on actual target hardware
- Ignoring linker script / memory map differences between boards (different flash/RAM sizes, different sections)