Platform Abstraction Requirements¶
This section defines requirements for the platform abstraction layer (PAL), which enables OpenSOMEIP to run on multiple operating systems and RTOSes.
Overview¶
The platform abstraction layer provides portable interfaces for:
Threading (Thread, Mutex, ConditionVariable, ScopedLock, sleep_for)
Memory management (Message pool allocation)
Networking (socket API abstraction)
Byte-order conversion
Each platform backend implements these interfaces in a *_impl.h
header selected at build time via CMake include-path configuration.
PAL Architecture¶
The platform abstraction shall use a build-system-selected include-path mechanism:
Rationale: Eliminates unmaintainable Code Location: |
PAL Interface Contracts¶
Mutex Interface¶
Rationale: Exclusive locking is the fundamental synchronization primitive used by SD, TP, and transport layers. Code Location: |
Rationale: Timely release prevents deadlock and ensures progress. Code Location: |
Rationale: Non-blocking acquisition is needed for lock-free polling patterns and diagnostic probes. Code Location: |
Rationale: Mutex identity is tied to its OS resource handle; copying would create dangling or aliased handles. Code Location: |
The Mutex implementation shall not corrupt internal state if Rationale: Double-unlock is a common programming error; the PAL must not crash or corrupt state. Error Handling: Platform-defined (POSIX: undefined; FreeRTOS: xSemaphoreGive returns pdFAIL; Zephyr: k_mutex_unlock returns -EPERM). Code Location: |
ConditionVariable Interface¶
Rationale: Atomic release-and-wait is the fundamental building block for producer/consumer patterns in SD and event delivery. Code Location: |
Rationale: Predicate-based wait eliminates spurious-wakeup bugs at the API level. Code Location: |
Rationale: Single-wake avoids thundering-herd effects on SD message dispatch. Code Location: |
Rationale: Broadcast wake is needed for shutdown sequences where all worker threads must unblock. Code Location: |
On all exit paths from Rationale: Mutex ownership loss after wait leads to data races that are extremely hard to diagnose. Code Location: |
If the predicate throws during Rationale: Exception-unsafe CV wrappers cause mutex ownership loss, leading to data races. Error Handling: RAII guard calls Code Location: |
Thread Interface¶
Rationale: Immediate-start semantics match Code Location: |
Rationale: Callers must check joinability before calling join() to avoid double-join errors. Code Location: |
Rationale: Join is the primary mechanism for safe thread shutdown in transport and SD layers. Code Location: |
Rationale: Thread identity is tied to an OS thread handle; copying would create invalid aliases. Code Location: |
If the underlying OS fails to create a thread (e.g., stack exhaustion
on FreeRTOS, thread limit on Zephyr), the Thread object shall be in a
non-joinable state and Rationale: Embedded systems have limited thread resources; failure must be handled gracefully. Error Handling: Code Location: |
The Thread destructor shall safely abort a running thread if
Rationale: Forgetting to join is a common error; the destructor must clean up without undefined behavior. Error Handling: Call platform-specific abort (vTaskDelete, k_thread_abort) and free context. Code Location: |
ScopedLock Interface¶
The Rationale: Automatic acquisition on construction ensures the critical section begins at the point of declaration. Code Location: |
The Rationale: Automatic release on scope exit prevents mutex leaks on early returns and exceptions. Code Location: |
Rationale: Copying a lock guard would create double-unlock on destruction. Code Location: |
sleep_for Interface¶
Rationale: SD timers and TP reassembly timeout rely on sleep_for providing a minimum delay guarantee. Code Location: |
Rationale: Prevents accidental infinite blocks when computed durations are zero or negative. Code Location: |
Memory Interface¶
Rationale: Decouples message lifetime management from the platform memory strategy (heap vs. pool). Code Location: |
Multiple calls to Rationale: Protocol layers allocate messages concurrently; aliased objects would cause data corruption. Code Location: |
When the platform’s message pool is exhausted,
Rationale: Embedded pools have fixed capacity; callers must handle exhaustion gracefully. Error Handling: Return Code Location: |
Pool-based Rationale: Transport and SD layers allocate messages from different threads. Error Handling: Mutex-protected allocation path. Code Location: |
Networking Interface¶
Rationale: Portable socket close is needed because POSIX uses
Code Location: |
Rationale: Graceful TCP shutdown requires separate shutdown before close. Code Location: |
Rationale: Non-blocking I/O is required for event-driven transport receive loops. Code Location: |
Rationale: Some operations (e.g., TCP connect) benefit from blocking mode with timeout. Code Location: |
Rationale: Transport layers check the return value to detect invalid socket states. Error Handling: Return Code Location: |
Byte-Order Interface¶
Rationale: SOME/IP Service ID, Method ID, and Length fields are 16-bit big-endian on the wire. Code Location: |
Rationale: Parsing incoming SOME/IP headers requires converting wire-format 16-bit fields to host order. Code Location: |
Rationale: SOME/IP Message ID and Length are serialized as 32-bit big-endian values. Code Location: |
Rationale: Parsing incoming SOME/IP headers requires converting wire-format 32-bit fields to host order. Code Location: |
Platform Backends¶
POSIX/Host Backend¶
The POSIX/host backend shall implement the PAL threading primitives using C++ standard library types:
Rationale: POSIX/host is the primary development and CI platform; standard library types provide zero-overhead abstractions. Code Location: |
The POSIX/host backend shall implement Rationale: On host/desktop, heap allocation is the natural choice; no pool is needed. Code Location: |
The POSIX/host backend shall provide networking through standard BSD
socket headers (
Rationale: POSIX sockets are the reference networking API. Code Location: |
The POSIX/host backend shall map byte-order macros to
Rationale: POSIX provides standard network byte-order functions. Code Location: |
FreeRTOS Backend¶
The FreeRTOS backend shall implement the PAL threading primitives:
Rationale: FreeRTOS is one of the most widely used RTOSes in automotive embedded systems. Code Location: |
The FreeRTOS backend shall provide a static pool allocator for Message objects:
Rationale: Embedded targets require deterministic memory allocation without heap fragmentation. Code Location: |
ThreadX Backend¶
The ThreadX backend shall implement the PAL threading primitives:
Rationale: ThreadX (Azure RTOS) is widely used in automotive and industrial embedded systems. Code Location: |
The ThreadX backend shall provide a static pool allocator for Message objects:
Rationale: Embedded targets require deterministic memory allocation without heap fragmentation. Code Location: |
lwIP Backend¶
The lwIP backend shall provide networking through lwIP’s socket layer:
Rationale: lwIP is the standard TCP/IP stack for FreeRTOS and ThreadX on microcontrollers. Code Location: |
The lwIP backend shall map byte-order macros to lwIP definitions from
Rationale: lwIP provides its own byte-order functions optimized for the target architecture. Code Location: |
Zephyr Backend¶
The Zephyr backend shall implement the PAL threading primitives:
Rationale: Zephyr is the RTOS with native SOME/IP SD multicast support used in OpenSOMEIP CI. Code Location: |
The Zephyr backend shall provide Rationale: Zephyr provides kernel-managed memory pools suitable for deterministic embedded allocation. Code Location: |
The Zephyr backend shall provide networking through Zephyr’s
Rationale: Zephyr removed Code Location: |
The Zephyr backend shall map byte-order macros to
Rationale: Zephyr provides endian-aware byte-order functions. Code Location: |
Win32 Backend¶
The Win32 backend shall implement the PAL threading primitives using C++ standard library types (identical to POSIX/host):
Rationale: Windows support enables development on Windows workstations. Code Location: |
The Win32 backend shall implement Rationale: Desktop Windows uses standard heap allocation. Code Location: |
The Win32 backend shall provide networking through Winsock2:
Rationale: Winsock2 is the standard networking API on Windows. Code Location: |
The Win32 backend shall map byte-order macros to Winsock2 functions. Rationale: Winsock2 provides standard byte-order functions on Windows. Code Location: |