Skip to content

S32K1 to S32K3 Migration

Everything so far has been S32K1: a Cortex-M4F, the S32 SDK, PCC clock gates, PORT/GPIO, and driver calls shaped like FLEXCAN_DRV_Init. NXP's current generation is S32K3, and it is not an incremental part change — it is a different core, a different peripheral vocabulary, a different driver stack, and a different boot process. Teams migrating for the first time consistently underestimate it. This module is the map: what carries over unchanged, what is renamed, what is genuinely new, and what will stop your first build cold.

The headline differences

Aspect S32K1xx S32K3xx
Core Cortex-M0+ (S32K11x) or Cortex-M4F (S32K14x) Cortex-M7, single / dual / lockstep
Max frequency 80 MHz RUN, up to 112 MHz HSRUN on S32K14x 160 MHz on most parts; up to 240 MHz on the largest
Caches / TCM None I-cache, D-cache, ITCM and DTCM
Safety target Systems up to ASIL B Systems up to ASIL D (lockstep, FCCU, self-test)
Driver stack S32 SDKPERIPH_DRV_Function() RTD (Real-Time Drivers) — AUTOSAR MCAL + low-level IP layer
Configuration Processor Expert / S32 Config Tools S32 Configuration Tools (MCAL-style, .epc)
Security CSEc (FlexNVM-backed key store) HSE — a separate security core running NXP firmware
Boot Vector table at 0x0000_0000, straight to your reset handler BAF validates an IVT, then jumps to your image

Peripheral vocabulary

This table is the one to keep open during a port. Roughly half the peripherals keep their names and most of their behaviour; the other half are replaced by parts with a Power Architecture heritage.

Function S32K1 S32K3
Pin mux + GPIO PORT (PCR[n]) + GPIO (PDDR/PDOR) SIUL2 (MSCR[n] output/mux, IMCR[n] input mux)
Clock generation SCG (SOSC/SIRC/FIRC/SPLL) MC_CGM + FXOSC/FIRC/PLL_DIG
Clock gating / modes PCC per-peripheral gates, SMC modes MC_ME (mode entry) + partition clock control
Watchdog WDOG SWT (Software Watchdog Timer)
Periodic timer LPIT PIT and STM (system timer module)
PWM / motor control FTM eMIOS
DMA eDMA + DMAMUX eDMA + DMAMUX (very similar)
CAN FlexCAN (+ CAN FD) FlexCAN — more instances, more MBs, CAN FD standard
Serial LPUART, LPSPI, LPI2C Same names, same programming model
ADC ADC (SAR) + PDB trigger ADC (SAR) + BCTU (body cross triggering unit)
Trigger routing TRGMUX TRGMUX
Fault handling Individual error flags FCCU (Fault Collection and Control Unit)
Memory errors ECC flags per module MEMU (Memory Error Management Unit)
Self-test STCU2 (LBIST / MBIST at startup)

Notice what survived: LPUART, LPSPI, LPI2C, FlexCAN, eDMA, TRGMUX. If your S32K1 code is well layered, the drivers for those port with modest effort. What does not survive is anything touching pins, clocks, or timers — which, unfortunately, is everything in your board bring-up.

Memory map

The addresses move, and this catches people whose linker scripts or bootloaders assume S32K1 layout:

Region S32K1xx S32K3xx
Code flash 0x0000_0000 0x0040_0000
Data flash 0x1000_0000 (FlexNVM) 0x1000_0000
SRAM 0x1FFF_xxxx (SRAM_L) / 0x2000_0000 (SRAM_U) 0x2040_0000
ITCM 0x0000_0000
DTCM 0x2000_0000
Factory/OTP region IFR, reached through flash commands 0x1B00_0000 (UTEST), directly addressable

The S32K3's ITCM at 0x0000_0000 is a genuine trap: code that assumed "address 0 is flash" — a bootloader reading a vector table, say — now reads tightly-coupled memory instead.

From the SDK to RTD

The same operation, both generations. S32K1, toggling an LED:

/* S32K1 — S32 SDK */
PINS_DRV_Init(NUM_PINS, g_pin_mux_InitConfigArr);
PINS_DRV_ClearPins(PTD, (1u << 15));      /* LED on  */
PINS_DRV_SetPins(PTD,   (1u << 15));      /* LED off */

S32K3, the same thing through RTD's two layers — the AUTOSAR MCAL API, or the low-level IP driver underneath it:

/* S32K3 — RTD, AUTOSAR MCAL layer */
Port_Init(&Port_Config);
Dio_WriteChannel(DioConf_DioChannel_LED_RED, STD_LOW);

/* S32K3 — RTD, low-level IP layer (leaner, non-AUTOSAR) */
Siul2_Port_Ip_Init(NUM_PORT_CFG, g_pin_mux_InitConfigArr);
Siul2_Dio_Ip_WritePin(LED_RED_PORT, LED_RED_PIN, 0u);

RTD ships both: *_Ip_* functions are the direct hardware layer, and the AUTOSAR-named modules (Port, Dio, Can, Adc, Mcu, Spi) sit on top for projects that need MCAL conformance. For a non-AUTOSAR project the IP layer is closer in spirit to the S32 SDK you already know, and it is the sensible target for a first port.

The equivalent shift for CAN: FLEXCAN_DRV_Init becomes either Can_Init() (MCAL) or FlexCAN_Ip_Init() (IP layer). The mailbox, filtering, and bus-off concepts from module 1 transfer completely — the hardware is recognisably the same FlexCAN.

Boot: the IVT and the BAF

An S32K1 boots by fetching the initial stack pointer and reset vector from address 0. An S32K3 does not. Its BAF (Boot Assist Firmware, in ROM) first reads an IVT (Image Vector Table) from a fixed flash location. The IVT holds the application's start address, configuration words, and — if secure boot is enabled — the parameters the HSE uses to authenticate the image. A device with a blank or invalid IVT does not run your code, no matter how correct your application is. Your build must emit a valid IVT, and your flash tool must program it.

Two more first-day surprises:

  • Reading erased flash raises an ECC error. On S32K3, uninitialized flash has no valid ECC, so reading it faults rather than returning 0xFF. Bootloaders that scan for "is there an application here?" by reading bytes must be rewritten to check a marker they wrote, never to probe blank memory.
  • Flash writes are wider. The write granularity is larger than the S32K1's 8-byte phrase, and page-aligned. Any NVM code from module 6 needs its alignment constants revisited.

Safety and security hardware

  • Lockstep. On lockstep parts, two Cortex-M7 cores execute the same instruction stream and hardware compares the results every cycle. A mismatch goes to the FCCU. This is the mechanism behind the ASIL D claim, and it costs you the second core — a dual-core part in lockstep is a single-core part with checking.
  • FCCU. A central collector for fault sources (lockstep mismatch, ECC errors, clock monitors, self-test failures) with configurable reactions: interrupt, reset, or driving an external error-out pin that tells the rest of the system this ECU is untrustworthy.
  • STCU2. Runs logic and memory built-in self-tests at startup (and, optionally, periodically) — real coverage numbers for the hardware metrics ISO 26262 requires, at the cost of boot time you must budget.
  • MEMU. Records and reports ECC events across memories so software can distinguish a corrected single-bit event (log it, watch the rate) from an uncorrectable one (fault reaction).
  • HSE. A separate security subsystem running NXP-supplied firmware, handling key storage, secure boot, and cryptographic services. It replaces CSEc and is considerably more capable — and it must be provisioned, which is a production-process question, not just a firmware one.

Migration checklist

  1. Separate your code into hardware-dependent and application layers before migrating. The application logic — filtering, state machines, CAN signal packing, diagnostics — should port unchanged. If it does not, that is the finding, not the port.
  2. Rebuild the bring-up layer first: clocks (MC_CGM/MC_ME), pins (SIUL2), watchdog (SWT), a timer, and a UART. Get "hello" out of a serial port before touching anything else.
  3. Produce a valid IVT and confirm the part actually boots your image.
  4. Port CAN next — it is the most familiar peripheral and gives you a diagnostic channel.
  5. Revisit every timing assumption. Caches, TCM, and 160 MHz change execution times in both directions; code that "was fast enough" needs re-measuring, not re-assuming.
  6. Enable the safety hardware deliberately: decide the FCCU reaction for each fault source and write it down. Defaults are not a safety concept.

Cheat sheet

Item S32K1 S32K3
Core Cortex-M4F @ ≤112 MHz Cortex-M7 @ 160 MHz+, lockstep options
Drivers S32 SDK FLEXCAN_DRV_Init RTD: Can_Init (MCAL) or FlexCAN_Ip_Init (IP)
Pins PORT->PCR[n] + PTx SIUL2 MSCR[n] / IMCR[n]
Clocks SCG + PCC MC_CGM + MC_ME
Watchdog WDOG SWT
PWM FTM eMIOS
Periodic timer LPIT PIT / STM
ADC trigger PDB BCTU
Unchanged LPUART, LPSPI, LPI2C, FlexCAN, eDMA, TRGMUX same
Code flash base 0x0000_0000 0x0040_0000 (ITCM now at 0)
Boot Vector table at 0 BAF validates the IVT first
Erased flash Reads 0xFF ECC error on read
Safety ECC, WDOG, clock monitor + FCCU, MEMU, STCU2, lockstep
Security CSEc HSE firmware-based subsystem

How It Actually Works

The jump from S32K1 to S32K3 isn't a peripheral refresh — it's a different silicon safety architecture. S32K1 achieves its safety island largely through software-visible self-test hardware (like flash ECC and a single lockstep option on select parts); S32K3 bakes in a genuine dual-core lockstep pair by default on many variants, where a checker core physically replicates the main core's logic and runs the identical instruction stream offset by a fixed number of clock cycles, with a hardware comparator continuously checking every bus transaction and register result between the two — a mismatch triggers an immediate safety-fault signal at the hardware level, independent of any software fault handler, because the comparator sits in the silicon's control path, not in an interrupt service routine that could itself be corrupted by the same fault.

S32K3's memory system also adds a hardware MPU (Memory Protection Unit) with finer-grained region control and an ECC scheme that covers more of the internal bus fabric, not just flash/SRAM arrays — this matters for AUTOSAR "freedom from interference" requirements (covered later in this course), because partitioning software into memory regions is only a real safety mechanism if the hardware actually enforces the boundary on every single bus transaction, including ones initiated by DMA, not just CPU loads/stores.

Clock and power architecture on S32K3 also moves to a more segmented tree with independently gateable domains per peripheral cluster, which is why S32K3 parts can hit substantially higher pin counts and peripheral density than S32K1 while still meeting the same automotive power budgets — more of the chip can be clock-gated off simultaneously because domain boundaries were drawn finer in the silicon.

(Described from the S32K1 and S32K3 reference manuals' architecture overview chapters; not measured on physical silicon in this course.)

Exercise

You do not need an S32K3 board to do the valuable part of this module. (1) Take your Level 1 capstone and produce a port assessment: go file by file and classify every function as portable, needs-rework, or rewrite, with the S32K3 peripheral named for each rewrite. The ratio you end up with is a direct measure of how well-layered your code was. (2) Rewrite one bring-up function — pin initialization — twice: once as it is today with PINS_DRV_*, once as it would be with Siul2_Port_Ip_* and Siul2_Dio_Ip_*, and note every assumption that broke. (3) Write the timing-review list: which of your timing assumptions came from the 80 MHz M4F, and how would you re-measure each on a cached M7? (4) Draft the FCCU reaction table for your node: for lockstep mismatch, uncorrectable ECC, clock loss, and self-test failure, state the reaction (interrupt / reset / error-out) and justify it against your safe state from module 9. If you do have an S32K3 evaluation board, add: get a UART "hello" out with RTD, and document exactly how many steps it took to produce a bootable IVT — that number is the real answer to "how hard is the migration?"