S19 File Format (Motorola S-Record): Complete Practical Guide for Embedded Firmware and Bootloaders
Suggested title: S19 File Format (Motorola S-Record): Complete Practical Guide for Embedded Firmware and Bootloaders
Suggested meta description: Understand the S19 file format used in embedded firmware updates and automotive ECU programming. Learn S-record structure, checksum, STM32 generation, bootloader flashing, CAN/UDS context, troubleshooting, and best practices.
Suggested URL slug: s19-motorola-s-record-file-format-guide
Featured Image Suggestion
- A high-resolution engineering-themed image showing: microcontroller board + hex editor + CAN analyzer + bootloader flow overlay.
- Suggested alt text: “S19 Motorola S-record firmware file used in embedded bootloader update workflow”.
Diagram Suggestions
- S-record line anatomy (Type, Count, Address, Data, Checksum)
- Address map from S19 records to MCU flash sectors
- Build-to-flash pipeline: ELF -> S19 -> transport packets -> bootloader write
- UDS download sequence with where S19 fits
What Is an S19 File?
An S19 file is a text-based firmware container format from the Motorola S-record family. It stores binary firmware as ASCII hex records, each record carrying:
- Record type
- Byte count
- Target memory address
- Data bytes
- Checksum
In practice, an S19 file answers one key embedded question:
“Which bytes must be programmed to which addresses on the target device?”
That is why it appears in:
- Bootloader firmware updates
- Automotive ECU programming
- Manufacturing programming stations
- Field updates over constrained links
Why Does S19 Exist?
Raw binary is compact, but difficult to inspect and fragile in text-oriented tooling. S19 solved practical problems early embedded teams had:
- Transfer firmware reliably over serial links and text channels
- Preserve address information with data
- Detect corruption record-by-record using checksum
- Support partial programming and sparse memory maps
It is still used because those problems still exist.
Why S19 Is Still Widely Used in Embedded Systems
Even with modern pipelines, S19 remains valuable because it is:
- Human-readable enough for debug and audits
- Easy for bootloaders to parse
- Good for segmented flash images
- Accepted by legacy and current tools across vendors
- Well understood in safety and automotive workflows
For engineers using STM32, NXP, TI, Renesas, or custom ECUs, S19 is still a practical bridge between build output and programming tools.
History: Motorola S-Record Origins
Motorola introduced S-records decades ago for programming and transporting code images across development and production systems. At the time, text-based interchange with embedded address metadata was a major operational win.
Over time, S-record became an industry convention outside Motorola ecosystems because:
- It is simple to implement
- It is robust enough for manufacturing flows
- Tooling support became universal
- It works across architectures and memory maps
This is why you still see S-records in modern ARM projects and in classic automotive flashing ecosystems.
S19 and Firmware Programming / Bootloaders
A bootloader typically needs three things from an update image:
- Where to write
- What to write
- Basic integrity check
S19 gives exactly that in each line. A typical parser loop is:
- Read one S-record line
- Validate checksum
- Extract address and data
- Program flash
- Continue until termination record
Because of this line-by-line behavior, S19 fits low-memory bootloaders and incremental communication channels.
S-Record File Structure in Detail
An S-record line has this generic layout:
S<type><count><address><data><checksum>
All fields are ASCII hex.
Record Types You Actually Use
| Record | Purpose | Typical Use |
|---|---|---|
| S0 | Header | Metadata (module name, version, comments) |
| S1 | Data with 16-bit address | Small address space targets |
| S2 | Data with 24-bit address | Mid-range address space |
| S3 | Data with 32-bit address | Modern MCUs/SoCs (common) |
| S5 | Record count | Number of data records sent |
| S7 | Start address (for S3 format) | Execution start address |
| S8 | Start address (for S2 format) | Execution start address |
| S9 | Start address (for S1 format) | Execution start address |
Field Meaning
1. Record Type
The character after S defines record semantics and address width.
2. Byte Count
count includes:
- Address bytes
- Data bytes
- Checksum byte
It does not include the leading S and type field.
3. Address Field
Address width depends on record type:
- S1/S9: 2 bytes
- S2/S8: 3 bytes
- S3/S7: 4 bytes
4. Data Field
Firmware payload bytes to be written into target memory.
5. Checksum
One-byte checksum is the ones complement of the least significant byte of:
- Count + address bytes + data bytes
Formula:
$$ \text{checksum} = \sim\left(\left(\sum \text{bytes}\right) & 0xFF\right) & 0xFF $$
Validation rule:
$$ (\text{count} + \text{address bytes} + \text{data bytes} + \text{checksum}) & 0xFF = 0xFF $$
Visual Diagram: Record Breakdown
flowchart LR
A[S3] --> B[0D Count]
B --> C[08000000 Address]
C --> D[2000002029050008 Data]
D --> E[9D Checksum]
Example Breakdown
S30D0800000020000020290500089D
S3-> Data record, 32-bit address0D-> 13 bytes follow (address + data + checksum)08000000-> Flash address2000002029050008-> 8 data bytes9D-> Checksum
Visual Diagram: Address Mapping
flowchart TB
A[S3 @ 0x08000000] --> B[Flash Sector 0]
C[S3 @ 0x08004000] --> D[Flash Sector 1]
E[S3 @ 0x08008000] --> F[Flash Sector 2]
S19 does not require contiguous addresses. Sparse records are valid and common.
Multiple Real S19 Examples with Line-by-Line Decoding
Example Set A: Typical 32-bit MCU Image (S3/S7)
S00C000053544D33325F415050D7
S30D0800000020000020290500089D
S30D08000008314800F021F800BF90
S5030002FA
S70508000000F2
Line 1
S00C000053544D33325F415050D7
S0: Header0C: 12 bytes after count0000: Header address (usually 0)53544D33325F415050: ASCII “STM32_APP”D7: Checksum
Line 2
S30D0800000020000020290500089D
S3: Data record, 32-bit address0D: 13 bytes follow08000000: Target flash address2000002029050008: Data9D: Checksum
Line 3
S30D08000008314800F021F800BF90
S3: Data record0D: 13 bytes follow08000008: Next address314800F021F800BF: Data90: Checksum
Line 4
S5030002FA
S5: Count record03: 3 bytes follow0002: Two data records transmitted (the two S3 lines)FA: Checksum
Line 5
S70508000000F2
S7: Start execution address for S3-type image05: 5 bytes follow08000000: Entry pointF2: Checksum
Example Set B: 16-bit Address Space (S1/S9)
S1130000285F245F2212226A000424290008237C2A
S107080012345678DC
S9030800F4
Decode
- First line is a classic S1 record with 16-bit address
0000and 16 data bytes. - Second line writes
12 34 56 78to address0800. - Last line (
S9) gives 16-bit start address0800.
Example Set C: 24-bit Address Space (S2/S8)
S208001234DEADBEEFC7
S804001000EB
Decode
S2line writesDE AD BE EFto 24-bit address0x001234.S8line defines 24-bit start address0x001000.
Checksum Interpretation Walkthrough
Take this record:
S107080012345678DC
Fields:
- Count =
0x07 - Address bytes =
0x08,0x00 - Data bytes =
0x12,0x34,0x56,0x78
Sum:
$$ 0x07 + 0x08 + 0x00 + 0x12 + 0x34 + 0x56 + 0x78 = 0x123 $$
Low byte:
$$ 0x23 $$
Ones complement:
$$ \sim0x23 = 0xDC $$
Checksum is DC, which matches the record.
How S19 Files Are Generated in Real Toolchains
Most flows generate S19 from ELF after linking.
GCC / ARM GCC
arm-none-eabi-objcopy -O srec build/app.elf build/app.s19
Common variants:
arm-none-eabi-objcopy -O srec --srec-forceS3 build/app.elf build/app.s19
arm-none-eabi-objcopy -O srec --remove-section=.comment build/app.elf build/app.s19
STM32CubeIDE
STM32CubeIDE uses GCC under the hood. Typical options:
- Post-build step with
arm-none-eabi-objcopy -O srec - Or generate via external tool in build pipeline
Example post-build command:
arm-none-eabi-objcopy -O srec "${BuildArtifactFileName}" "${BuildArtifactFileBaseName}.s19"
IAR Embedded Workbench
- Build output can include Motorola S-record through output converter settings.
- Teams often standardize this in project options for production artifacts.
Keil MDK (ARMClang / ARMCC)
- Use
fromelfor output conversion tools to produce S-record from AXF/ELF. - Typical CI setup exports both
.binand.s19for different flashing paths.
srec_cat for Processing and Validation
Useful operations:
srec_cat app.s19 -o app_padded.s19 -fill 0xFF 0x08000000 0x08020000
srec_cat app.s19 -o app.bin -binary
srec_cat app.s19 -crop 0x08000000 0x08010000 -o app_crop.s19
S19 vs Intel HEX vs BIN vs ELF
| Format | Contains Addresses | Human-readable | Metadata/Symbols | Typical Use | Pros | Cons |
|---|---|---|---|---|---|---|
| S19 (Motorola S-record) | Yes | Yes (ASCII hex) | No symbols | Bootloader/programming | Robust text format, widely supported, easy parser | Larger than BIN, limited metadata |
| Intel HEX | Yes | Yes (ASCII hex) | No symbols | Similar to S19 | Very common, tooling-rich | Similar overhead as S19 |
| BIN | No (raw bytes only) | No | No | Direct flash at fixed base | Small and simple | Needs external base address knowledge |
| ELF | Yes (sections/segments) | Partly (not line-based) | Yes (debug symbols etc.) | Build/debug/link artifacts | Richest metadata, debug-friendly | Complex for simple bootloaders |
Practical reality:
- Development/debug: ELF
- Production transport/programming: S19 or HEX
- Minimal direct write path: BIN
Real-World Usage
Automotive ECUs
S19 is heavily used in ECU reprogramming flows where address-annotated, checksummed records are needed for controlled flashing.
Bootloaders
Custom and vendor bootloaders parse S19 for:
- Internal flash updates
- External QSPI/EEPROM staging
- A/B firmware partitions
Firmware Updates
S19 supports partial updates by sending only changed ranges.
CAN-Based Flashing
CAN frames carry transport-layer chunks; S19 remains the image source format before chunking.
UDS Firmware Download Procedures
In UDS workflows, application tools parse S19 and send data via:
RequestDownloadTransferDataRequestTransferExit
The UDS layer does transport/session control; S19 provides address+data source.
Manufacturing and Production Programming
Programming stations use S19 for deterministic address mapping and traceable checksum validation.
OTA Update Preparation
Backend pipelines often:
- Generate S19 from ELF
- Validate ranges
- Convert/split/encrypt/sign as required
- Package for OTA campaign
Relationship Clarification: S19 vs CAN vs UDS vs IDE vs Bootloader
S19 and CAN Bus
- CAN is a communication bus.
- S19 is a firmware file format.
S19 data may be transported over CAN, but S19 is not a CAN protocol.
S19 and UDS
- UDS is a diagnostic/flash protocol.
- S19 is one possible firmware input to the UDS flashing tool.
S19 is not UDS.
S19 and STM32CubeIDE
- STM32CubeIDE can generate S19 from ELF.
- IDE is build tooling; S19 is output artifact.
S19 and Bootloaders
- Bootloader consumes parsed address+data records.
- S19 is one common container the bootloader toolchain understands.
Practical STM32 Example: Build -> Generate S19 -> Transfer -> Flash
1. Build Firmware
cmake --build build --config Release
(or build from STM32CubeIDE GUI/CLI)
2. Generate S19
arm-none-eabi-objcopy -O srec build/stm32_app.elf build/stm32_app.s19
3. Inspect/verify image ranges
srec_cat build/stm32_app.s19 -Output_Block_Size 16 -o - -hex_dump
4. Optional conversion for another tool
srec_cat build/stm32_app.s19 -o build/stm32_app.bin -binary
5. Transfer to target (example paths)
- UART bootloader host tool
- CAN/UDS flasher that parses S19 and sends chunks
- SWD/JTAG production script that accepts S-record
6. Bootloader flash flow on target
- Erase target sectors
- Program incoming records by address
- Verify programmed bytes
- Validate image integrity (CRC/signature if applicable)
- Set boot flag and reset
Command-Line Snippets You Will Actually Use
objcopy
arm-none-eabi-objcopy -O srec app.elf app.s19
arm-none-eabi-objcopy -O binary app.elf app.bin
srec_cat transformations
srec_cat app.s19 -crop 0x08000000 0x08020000 -o app_main.s19
srec_cat app.s19 -offset -0x08000000 -o app_offset.s19
Basic checksum verification idea
# Conceptual check: parse each S-record and ensure
# (count + address + data + checksum) & 0xFF == 0xFF
In CI, this is typically done via script or S-record utility.
Troubleshooting Guide
1. Invalid Checksum
Symptoms:
- Flasher rejects specific lines
- Bootloader aborts transfer
Checks:
- Line corruption in transport/log copy
- Wrong newline handling
- Manual edits that broke checksum
Fix:
- Regenerate from ELF
- Re-run checksum validation before flashing
2. Wrong Memory Address
Symptoms:
- Device boots to hard fault
- Vector table not found
- App writes into bootloader region
Checks:
- Linker script memory origin/length
- Bootloader expected application base address
- S-record type/address width consistency
Fix:
- Align linker script and bootloader configuration
3. Bootloader Rejection
Symptoms:
- “Unsupported record type”
- “Address out of range”
- “Image not valid”
Checks:
- Bootloader supports S1 only but image is S3
- Security policy requires signature/header
- Missing terminal record (S7/S8/S9)
Fix:
- Generate compatible record format
- Add required manifest/signature stage
4. Missing Records
Symptoms:
- Partial programming
- Random app behavior
Checks:
- Transport truncation
- Tool filtering/cropping options
- Removed sections unintentionally
Fix:
- Compare programmed range against map file
- Validate record count (S5 vs actual data lines)
5. Endianness Misconceptions
Important:
- S19 byte order is exactly as bytes are stored at addresses.
- Endianness affects multi-byte interpretation by CPU, not S-record container semantics.
Industry Best Practices
- Keep ELF, S19, BIN as separate release artifacts with traceable versioning.
- Validate address ranges against allowed flash partitions before programming.
- Enforce checksum and file-level integrity checks in CI.
- Add cryptographic signing for production updates; checksum alone is not security.
- Freeze toolchain versions for reproducible S19 generation.
- Store map files with artifacts for post-flash debugging.
- Test bootloader parser against malformed records and boundary addresses.
- Log every programmed address block in manufacturing and service tools.
Frequently Asked Questions
Is S19 the same as Motorola S-record?
Yes. S19 usually refers to files in the Motorola S-record family.
Is S19 a communication protocol?
No. S19 is a firmware container format. Protocols are CAN, UDS, UART, Ethernet transport, etc.
Can I flash S19 directly with any programmer?
Only if the programmer/tool supports S-record parsing. Otherwise convert to BIN/HEX as needed.
Should I use S19 or BIN for bootloaders?
Use S19 when you need address metadata and line integrity checks. Use BIN when address is fixed and parser must be minimal.
Why do some files use S3 while others use S1?
Different address widths. Modern 32-bit MCU images usually use S3.
Does S19 include debug symbols?
No. Keep ELF for symbols and debugging.
Is checksum enough for secure OTA updates?
No. Checksum detects accidental corruption, not malicious tampering. Use cryptographic signatures and secure boot.
Summary and Key Takeaways
S19 remains a practical industry format because it solves real firmware programming needs with minimal complexity: address-aware records, line-level integrity checks, and broad tooling support.
For embedded and automotive teams:
- Treat S19 as a firmware container, not a protocol.
- Use it as the bridge between linker output and flashing transport.
- Keep your bootloader expectations, linker script, and S-record generation options aligned.
- Add modern integrity and security layers (hash/signature) on top of classic checksum.
If you build firmware update systems for STM32, NXP, TI, Renesas, or automotive ECUs, mastering Motorola S-record details pays off in reliability, diagnosability, and production robustness.
SEO Notes for Publishing
Primary keywords naturally covered in this article:
- S19 file format
- Motorola S-record
- firmware update
- embedded systems
- STM32 S19
- bootloader firmware
- UDS flashing
- automotive ECU programming