Status:** ACCEPTED
Date:** 2026-08-02
Author:** RteFramework Team
Category:** Data Integrity, Redundancy Support
Context
Problem Statement
Safety-critical systems with redundant channels (2oo2, 2oo3, etc.) must detect data corruption during transmission and channel-to-channel communication. Current approach (CRC-32 in examples) is adequate but not aligned with ERTMS/ETCS standards.
Requirements:**
- Detect random transmission errors (bit flips, noise)
- Detect systematic data corruption (buffer overflow, memory corruption)
- Work across vital channels and cluster communication
- Deterministic, bounded execution time (safety-critical)
- No dynamic memory (MISRA C:2012 compliance)
- Integrate seamlessly with redundancy voting logic
Existing Approaches
| Approach | Pros | Cons |
| No checksum | Simplest | Can't detect corruption |
| CRC-32 | Fast, proven | Lower error detection |
| CRC-64 | Better error detection, ERTMS standard | Slightly more overhead |
| HMAC/Signature | Cryptographic | Too slow for real-time, not needed for random errors |
Why CRC-64 is Right for RTE
- ERTMS Compliance: Railway systems standardize on CRC-64-CCITT (polynomial 0x1D4F63B86E40E541)
- Error Detection: Catches ~99.99% of random errors (vs ~99.9% for CRC-32)
- Performance: Lookup-table based (O(1) per byte), deterministic latency
- Simplicity: No keys or secrets, just polynomial-based math
- Integration: Can wrap vital messages transparently
Decision
ACCEPTED:** Implement CRC-64 as a built-in RTE module (rte_checksum) with:
- CRC-64 Computation
- Lookup-table based (pre-computed at compile-time)
- Three polynomial options: ERTMS (default), ISO, XZ
- O(1) execution per byte (deterministic)
- Full statistics and diagnostics
- Vital Message Wrapper
- rte_vital_message_t structure with integrated CRC-64
- Automatic CRC computation on send
- Automatic CRC verification on receive
- Sequence number checking (detect reordering)
- Timestamp for latency analysis
- Integration Points
- Core checksum API: rte_checksum_crc64(data, size)
- Message wrapper: rte_checksum_vital_message_*
- Statistics: rte_checksum_get_stats() for monitoring
- Error handling: Return RTE_STATUS_ERROR on CRC mismatch
Implementation
Module Structure (ADR-007 compliance)
include/rte/checksum/
├── rte_checksum.h # API definition
src/checksum/
├── rte_checksum.c # Implementation with LUT tables
├── CMakeLists.txt # Build configuration
tests/checksum/
├── test_crc64.c # CRC computation tests
├── test_vital_message.c # Message wrapper tests
└── test_integration.c # Redundancy integration tests
Key Design Decisions
1. Lookup Tables (Pre-computed)
Decision:** Generate CRC-64 lookup tables at compile-time (not runtime)
Rationale:**
2. Three Polynomial Options
ERTMS (Default):** 0x1D4F63B86E40E541
- Standard for railway signaling (EN 50126/50128)
- Used in ETCS/ERTMS RBC systems
Recommended for all new projects
ISO:** 0x000000000000001B
- ISO 3309, HDLC standard
Legacy communication protocols
XZ (LZMA):** 0x142F0E1EBA9EA3C3
- Alternative for high-reliability systems
Used in compression algorithms
Selection:** Default to ERTMS; user selects at initialization
3. Vital Message Wrapper
Structure:**
typedef struct {
uint32_t sequence_number;
uint32_t sender_id;
uint32_t timestamp_ms;
uint8_t payload_size;
uint8_t payload[248];
uint64_t crc64;
Vital channel message with integrated CRC-64.
Usage Pattern:**
- Sender: rte_checksum_vital_message_create() → CRC computed
- Network: Send 256-byte message
- Receiver: rte_checksum_vital_message_verify() → CRC checked
- Mismatch: Return RTE_STATUS_ERROR → trigger safe-state
4. Statistics & Monitoring
Track:
Architectural Fit
With Redundancy Framework (Future v0.4.0+)
↓
Payload data
↓
↓
Network transmission
↓
↓
Voting Logic (detect if A vs B payloads differ after CRC OK)
↓
Output or Safe-State
rte_status_t rte_checksum_vital_message_verify(const rte_vital_message_t *msg, uint32_t expected_sequence, uint8_t *payload_out, size_t payload_max_size, uint8_t *payload_size_out)
Verify vital channel message and extract payload.
rte_status_t rte_checksum_vital_message_create(rte_vital_message_t *msg_out, uint32_t sender_id, uint32_t sequence, const uint8_t *payload, size_t payload_size)
Create vital channel message with CRC.
rte_channel_storage_t rte_channel_t
Opaque handle to a vital channel instance.
Integration Benefits:**
- CRC catches transmission corruption (random errors)
- Voting catches calculation errors (systematic errors)
- Safe-state on ANY error (CRC fail OR voting fail)
With Existing Modules
Depends on:**
EN 50128 Compliance
Mandatory Techniques Supported
| Technique | How CRC-64 Helps |
| Defensive Programming (7.2.3) | Check all data with CRC before use |
| Error Detection (7.6.1) | Detect corruption via CRC mismatch |
| Fault Tolerance (7.6.1) | Trigger safe-state if CRC fails |
| Requirements Traceability (7.4.1) | REQ-ID links in code & docs |
Random vs Systematic Error Detection
Random Errors** (handled by CRC-64):
SIL Implications
SIL 1-2 (Single System)
CRC-64 optional but recommended for data integrity assurance:
if (result.match == 0) {
log_corruption_and_retry();
}
rte_status_t rte_checksum_crc64_verify(const uint8_t *data, size_t size, rte_crc64_t expected_crc, rte_checksum_result_t *result_out)
Verify CRC-64 of data against stored value.
SIL 3-4 (Redundant Systems)
CRC-64 mandatory for vital channel communication:
rte_safestate_trigger(REASON_DATA_CORRUPTION);
}
rte_status_t rte_ipc_send(rte_ipc_handle_t handle, const void *message, size_t message_size, rte_duration_ms_t timeout_ms)
Sends one message, blocking at most timeout_ms.
Implementation Timeline
Phase 1: Core API (v0.3.0)
- CRC-64 computation (ERTMS polynomial)
- Statistics tracking
- Full test suite
Phase 2: Integration (v0.4.0)
- Transparent CRC for vital channels
- Production deployment support
Phase 3: Advanced (Future)
- Additional polynomials (ISO, XZ)
- Hardware acceleration (if available)
- Per-site statistics aggregation
Risk Mitigation
| Risk | Mitigation |
| CRC collision (two different data same CRC) | ERTMS polynomial has good distribution; verify with testing |
| Performance overhead | Lookup-table O(1) keeps overhead <5% for typical 256-byte message |
| Lookup table size | 2KB acceptable for embedded; smaller/larger tables possible |
| Polynomial choice | Default ERTMS (railway standard); others available if needed |
Alternatives Considered
1. No Checksum (Status Quo)
Pros:** Simpler code, less overhead
Cons:** Can't detect corruption; fails EN 50128 error detection requirement
Decision:** Rejected — insufficient error detection
2. CRC-32 Only
Pros:** Smaller tables (512 bytes), commonly used
Cons:** Lower detection rate; not ERTMS standard
Decision:** Rejected — CRC-64 better for railway systems
3. HMAC-SHA256
Pros:** Cryptographically strong
Cons:** Too slow for real-time (msec → usec), overkill for random errors
Decision:** Rejected — not needed for railway safety
4. Hamming Codes
Pros:** Can correct single-bit errors
Cons:** Much more complex, doesn't help with multi-bit errors
Decision:** Rejected — CRC simpler for detect-and-safe-state model
Testing Strategy
Unit Tests
- CRC computation against known vectors
- Vital message creation/verification
- Corrupted payload detection
- Sequence number validation
Integration Tests
- CRC with actual IPC channels
- Multi-site cluster communication
- Failover with CRC verification
- Statistics collection
Property Tests
- CRC collision probability
- Performance benchmarks
- Execution time bounds
- Memory usage
Documentation
API Documentation
- Full Doxygen in rte_checksum.h
- Example code for each function
- Integration examples with redundancy
Architectural Documentation
- This ADR (architecture decision)
- How CRC fits with voting logic
- Troubleshooting guide
Certification Documentation
- EN 50128 compliance argument
- Safety case material
- Test reports
Rollout Plan
- Merge: Implement in v0.3.0 alongside watchdog
- Document: Add examples to HARDWARE_PATTERNS_GUIDE.dox
- Test: Full test suite and benchmarks
- Integrate: Use in redundancy APIs (v0.4.0)
- Release: Production support in v1.0
References
Approval
- Architect: Approved
- Safety Lead: Approved (meets EN 50128 error detection requirement)
- Performance: Approved (O(1) lookup, <5% overhead)
- Testing: Ready for implementation