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:

  1. Threading (Thread, Mutex, ConditionVariable, ScopedLock, sleep_for)

  2. Memory management (Message pool allocation)

  3. Networking (socket API abstraction)

  4. 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

Requirement: Platform Abstraction Layer Architecture REQ_PLATFORM_ARCH_001
status: implemented
priority: high

The platform abstraction shall use a build-system-selected include-path mechanism:

  • Public headers (thread.h, memory.h, net.h, byteorder.h) contain only common code and #include "*_impl.h"

  • No #if/#elif/#ifdef for platform detection in public headers

  • Each backend lives in its own directory under include/platform/

  • CMake sets the include path to select the correct backend

  • Adding a new platform = adding a directory + a CMake if() block

Rationale: Eliminates unmaintainable #ifdef chains and makes the platform layer extensible for future backends.

Code Location: include/platform/, CMakeLists.txt, src/CMakeLists.txt

PAL Interface Contracts

Mutex Interface

Requirement: PAL Mutex Lock REQ_PAL_MUTEX_LOCK

Mutex::lock() shall acquire exclusive ownership of the mutex. If another thread holds the mutex, the caller shall block until ownership is available.

Rationale: Exclusive locking is the fundamental synchronization primitive used by SD, TP, and transport layers.

Code Location: include/platform/posix/thread_impl.h, include/platform/freertos/thread_impl.h, include/platform/threadx/thread_impl.h, include/platform/zephyr/thread_impl.h

Requirement: PAL Mutex Unlock REQ_PAL_MUTEX_UNLOCK

Mutex::unlock() shall release exclusive ownership of the mutex, allowing other threads blocked on lock() to proceed.

Rationale: Timely release prevents deadlock and ensures progress.

Code Location: include/platform/posix/thread_impl.h, include/platform/freertos/thread_impl.h, include/platform/threadx/thread_impl.h, include/platform/zephyr/thread_impl.h

Requirement: PAL Mutex Try Lock REQ_PAL_MUTEX_TRYLOCK

Mutex::try_lock() shall attempt to acquire exclusive ownership without blocking. It shall return true if ownership was acquired and false otherwise.

Rationale: Non-blocking acquisition is needed for lock-free polling patterns and diagnostic probes.

Code Location: include/platform/posix/thread_impl.h, include/platform/freertos/thread_impl.h, include/platform/threadx/thread_impl.h, include/platform/zephyr/thread_impl.h

Requirement: PAL Mutex Non-Copyable REQ_PAL_MUTEX_NONCOPY
status: implemented
priority: medium
satisfies: REQ_ARCH_001

Mutex shall be non-copyable and non-movable. Copy constructor, copy-assignment, move constructor, and move-assignment shall be deleted.

Rationale: Mutex identity is tied to its OS resource handle; copying would create dangling or aliased handles.

Code Location: include/platform/freertos/thread_impl.h, include/platform/zephyr/thread_impl.h

Requirement: Error - Mutex Double Unlock REQ_PAL_MUTEX_UNLOCK_E01
status: implemented
priority: medium

The Mutex implementation shall not corrupt internal state if unlock() is called without a matching lock().

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: include/platform/freertos/thread_impl.h, include/platform/zephyr/thread_impl.h

ConditionVariable Interface

Requirement: PAL ConditionVariable Wait REQ_PAL_CV_WAIT

ConditionVariable::wait(Mutex& m) shall atomically release m and suspend the calling thread until a notification is received. Before returning, it shall re-acquire m.

Rationale: Atomic release-and-wait is the fundamental building block for producer/consumer patterns in SD and event delivery.

Code Location: include/platform/host/host_condition_variable.h, include/platform/freertos/thread_impl.h, include/platform/zephyr/thread_impl.h

Requirement: PAL ConditionVariable Wait with Predicate REQ_PAL_CV_WAIT_PRED

ConditionVariable::wait(Mutex& m, Pred pred) shall loop internally, re-checking pred() on each wakeup, and return only when pred() returns true. The Mutex shall be held on return.

Rationale: Predicate-based wait eliminates spurious-wakeup bugs at the API level.

Code Location: include/platform/host/host_condition_variable.h, include/platform/freertos/thread_impl.h, include/platform/zephyr/thread_impl.h

Requirement: PAL ConditionVariable Notify One REQ_PAL_CV_NOTIFY_ONE

ConditionVariable::notify_one() shall wake exactly one thread that is blocked in wait(). If no threads are waiting, the notification shall be a no-op.

Rationale: Single-wake avoids thundering-herd effects on SD message dispatch.

Code Location: include/platform/host/host_condition_variable.h, include/platform/freertos/thread_impl.h, include/platform/zephyr/thread_impl.h

Requirement: PAL ConditionVariable Notify All REQ_PAL_CV_NOTIFY_ALL

ConditionVariable::notify_all() shall wake all threads that are blocked in wait().

Rationale: Broadcast wake is needed for shutdown sequences where all worker threads must unblock.

Code Location: include/platform/host/host_condition_variable.h, include/platform/freertos/thread_impl.h, include/platform/zephyr/thread_impl.h

Requirement: PAL ConditionVariable Mutex Ownership Guarantee REQ_PAL_CV_OWNERSHIP

On all exit paths from wait() — normal return, predicate satisfaction, or exception propagation — the caller shall still hold the Mutex that was passed to wait().

Rationale: Mutex ownership loss after wait leads to data races that are extremely hard to diagnose.

Code Location: include/platform/host/host_condition_variable.h

Requirement: Error - ConditionVariable Exception Safety REQ_PAL_CV_EXCEPT_E01
status: implemented
priority: high

If the predicate throws during wait(Mutex&, Pred), the caller shall still own the Mutex when the exception propagates.

Rationale: Exception-unsafe CV wrappers cause mutex ownership loss, leading to data races.

Error Handling: RAII guard calls lk.release() on all exit paths.

Code Location: include/platform/host/host_condition_variable.h

Thread Interface

Requirement: PAL Thread Creation REQ_PAL_THREAD_CREATE

Thread shall be constructible from a callable (function, lambda, or functor) with optional arguments. Execution shall begin immediately upon construction.

Rationale: Immediate-start semantics match std::thread and simplify worker-thread creation in SD and transport layers.

Code Location: include/platform/posix/thread_impl.h, include/platform/freertos/thread_impl.h, include/platform/zephyr/thread_impl.h

Requirement: PAL Thread Joinable Query REQ_PAL_THREAD_JOINABLE

Thread::joinable() shall return true if the thread has been started and has not yet been joined, and false otherwise.

Rationale: Callers must check joinability before calling join() to avoid double-join errors.

Code Location: include/platform/freertos/thread_impl.h, include/platform/zephyr/thread_impl.h

Requirement: PAL Thread Join REQ_PAL_THREAD_JOIN

Thread::join() shall block the calling thread until the target thread completes execution. The call shall be idempotent: calling join() on an already-joined Thread shall be a safe no-op.

Rationale: Join is the primary mechanism for safe thread shutdown in transport and SD layers.

Code Location: include/platform/freertos/thread_impl.h, include/platform/zephyr/thread_impl.h

Requirement: PAL Thread Non-Copyable REQ_PAL_THREAD_NONCOPY
status: implemented
priority: medium
satisfies: REQ_ARCH_001

Thread shall be non-copyable and non-movable.

Rationale: Thread identity is tied to an OS thread handle; copying would create invalid aliases.

Code Location: include/platform/freertos/thread_impl.h, include/platform/zephyr/thread_impl.h

Requirement: Error - Thread Creation Failure REQ_PAL_THREAD_CREATE_E01
status: implemented
priority: high

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 join() shall be a safe no-op.

Rationale: Embedded systems have limited thread resources; failure must be handled gracefully.

Error Handling: started_ remains false; resources are freed in the constructor error path.

Code Location: include/platform/freertos/thread_impl.h, include/platform/zephyr/thread_impl.h

Requirement: Error - Thread Destructor Without Join REQ_PAL_THREAD_DTOR_E01
status: implemented
priority: medium

The Thread destructor shall safely abort a running thread if joinable() is true at destruction time, preventing resource leaks.

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: include/platform/freertos/thread_impl.h, include/platform/zephyr/thread_impl.h

ScopedLock Interface

Requirement: PAL ScopedLock Acquisition on Construction REQ_PAL_LOCK_ACQUIRE

The ScopedLock constructor shall call Mutex::lock() to acquire exclusive ownership of the associated mutex.

Rationale: Automatic acquisition on construction ensures the critical section begins at the point of declaration.

Code Location: include/platform/thread.h

Requirement: PAL ScopedLock Release on Destruction REQ_PAL_LOCK_RELEASE

The ScopedLock destructor shall call Mutex::unlock() to release exclusive ownership of the associated mutex.

Rationale: Automatic release on scope exit prevents mutex leaks on early returns and exceptions.

Code Location: include/platform/thread.h

Requirement: PAL ScopedLock Non-Copyable REQ_PAL_LOCK_NONCOPY
status: implemented
priority: medium
satisfies: REQ_ARCH_001

ScopedLock shall be non-copyable and non-assignable.

Rationale: Copying a lock guard would create double-unlock on destruction.

Code Location: include/platform/thread.h

sleep_for Interface

Requirement: PAL sleep_for Minimum Duration REQ_PAL_SLEEP_DURATION

someip::platform::this_thread::sleep_for(duration) shall block the calling thread for at least the specified duration. The actual sleep time may be longer due to scheduling jitter.

Rationale: SD timers and TP reassembly timeout rely on sleep_for providing a minimum delay guarantee.

Code Location: include/platform/posix/thread_impl.h, include/platform/freertos/thread_impl.h, include/platform/zephyr/thread_impl.h

Requirement: PAL sleep_for Zero Duration REQ_PAL_SLEEP_ZERO

sleep_for with a zero or negative duration shall return immediately without blocking.

Rationale: Prevents accidental infinite blocks when computed durations are zero or negative.

Code Location: include/platform/freertos/thread_impl.h, include/platform/zephyr/thread_impl.h

Memory Interface

Requirement: PAL Memory Allocation REQ_PAL_MEM_ALLOC

someip::platform::allocate_message() shall return a MessagePtr (std::shared_ptr<Message>) owning a fully constructed, usable Message object.

Rationale: Decouples message lifetime management from the platform memory strategy (heap vs. pool).

Code Location: include/platform/memory.h, include/platform/posix/memory_impl.h, include/platform/freertos/memory_impl.h, include/platform/threadx/memory_impl.h, include/platform/zephyr/memory_impl.h

Requirement: PAL Memory Independence REQ_PAL_MEM_INDEPENDENT

Multiple calls to allocate_message() shall return independent Message objects. Modifying one shall not affect the other.

Rationale: Protocol layers allocate messages concurrently; aliased objects would cause data corruption.

Code Location: include/platform/posix/memory_impl.h, include/platform/freertos/memory_impl.h

Requirement: Error - Memory Pool Exhaustion REQ_PAL_MEM_EXHAUST_E01
status: implemented
priority: high

When the platform’s message pool is exhausted, allocate_message() shall return nullptr without crashing or corrupting the pool.

Rationale: Embedded pools have fixed capacity; callers must handle exhaustion gracefully.

Error Handling: Return nullptr; pool internals remain consistent.

Code Location: include/platform/freertos/memory_impl.h, include/platform/threadx/memory_impl.h, src/platform/zephyr/memory.cpp

Requirement: Error - Memory Pool Thread Safety REQ_PAL_MEM_THREADSAFE_E01
status: implemented
priority: high

Pool-based allocate_message() implementations shall be thread-safe: concurrent allocations and releases shall not corrupt the pool or deadlock.

Rationale: Transport and SD layers allocate messages from different threads.

Error Handling: Mutex-protected allocation path.

Code Location: include/platform/freertos/memory_impl.h, include/platform/threadx/memory_impl.h, src/platform/zephyr/memory.cpp

Networking Interface

Requirement: PAL Socket Close REQ_PAL_NET_CLOSE
status: implemented
priority: high

someip_close_socket(fd) shall close the socket descriptor and release the associated OS resources.

Rationale: Portable socket close is needed because POSIX uses close() while Win32 uses closesocket().

Code Location: include/platform/posix/net_impl.h, include/platform/win32/net_impl.h, include/platform/lwip/net_impl.h, include/platform/zephyr/net_impl.h

Requirement: PAL Socket Shutdown REQ_PAL_NET_SHUTDOWN
status: implemented
priority: high

someip_shutdown_socket(fd) shall shutdown both read and write directions on the socket (equivalent to SHUT_RDWR / SD_BOTH).

Rationale: Graceful TCP shutdown requires separate shutdown before close.

Code Location: include/platform/posix/net_impl.h, include/platform/win32/net_impl.h, include/platform/lwip/net_impl.h, include/platform/zephyr/net_impl.h

Requirement: PAL Socket Set Non-Blocking REQ_PAL_NET_NONBLOCK
status: implemented
priority: high

someip_set_nonblocking(fd) shall set the socket to non-blocking mode and return 0 on success.

Rationale: Non-blocking I/O is required for event-driven transport receive loops.

Code Location: include/platform/posix/net_impl.h, include/platform/win32/net_impl.h, include/platform/zephyr/net_impl.h

Requirement: PAL Socket Set Blocking REQ_PAL_NET_BLOCK
status: implemented
priority: high

someip_set_blocking(fd) shall set the socket back to blocking mode and return 0 on success.

Rationale: Some operations (e.g., TCP connect) benefit from blocking mode with timeout.

Code Location: include/platform/posix/net_impl.h, include/platform/win32/net_impl.h, include/platform/zephyr/net_impl.h

Requirement: Error - Socket Mode Change Failure REQ_PAL_NET_MODE_E01
status: implemented
priority: medium

someip_set_nonblocking() and someip_set_blocking() shall return -1 when the underlying system call fails (e.g., invalid fd).

Rationale: Transport layers check the return value to detect invalid socket states.

Error Handling: Return -1; do not modify socket state.

Code Location: include/platform/posix/net_impl.h, include/platform/win32/net_impl.h, include/platform/zephyr/net_impl.h

Byte-Order Interface

Requirement: PAL Host-to-Network 16-bit Conversion REQ_PAL_BYTE_HTONS
status: implemented
priority: high

someip_htons(x) shall convert a 16-bit value from host byte order to network byte order (big-endian).

Rationale: SOME/IP Service ID, Method ID, and Length fields are 16-bit big-endian on the wire.

Code Location: include/platform/posix/byteorder_impl.h, include/platform/win32/byteorder_impl.h, include/platform/lwip/byteorder_impl.h, include/platform/zephyr/byteorder_impl.h

Requirement: PAL Network-to-Host 16-bit Conversion REQ_PAL_BYTE_NTOHS
status: implemented
priority: high

someip_ntohs(x) shall convert a 16-bit value from network byte order (big-endian) to host byte order.

Rationale: Parsing incoming SOME/IP headers requires converting wire-format 16-bit fields to host order.

Code Location: include/platform/posix/byteorder_impl.h, include/platform/win32/byteorder_impl.h, include/platform/lwip/byteorder_impl.h, include/platform/zephyr/byteorder_impl.h

Requirement: PAL Host-to-Network 32-bit Conversion REQ_PAL_BYTE_HTONL
status: implemented
priority: high

someip_htonl(x) shall convert a 32-bit value from host byte order to network byte order (big-endian).

Rationale: SOME/IP Message ID and Length are serialized as 32-bit big-endian values.

Code Location: include/platform/posix/byteorder_impl.h, include/platform/win32/byteorder_impl.h, include/platform/lwip/byteorder_impl.h, include/platform/zephyr/byteorder_impl.h

Requirement: PAL Network-to-Host 32-bit Conversion REQ_PAL_BYTE_NTOHL
status: implemented
priority: high

someip_ntohl(x) shall convert a 32-bit value from network byte order (big-endian) to host byte order.

Rationale: Parsing incoming SOME/IP headers requires converting wire-format 32-bit fields to host order.

Code Location: include/platform/posix/byteorder_impl.h, include/platform/win32/byteorder_impl.h, include/platform/lwip/byteorder_impl.h, include/platform/zephyr/byteorder_impl.h

Static Allocation Contracts

Container Interface

Requirement: Platform Vector Type REQ_PAL_CONTAINER_VECTOR
status: implemented
priority: high
satisfies: REQ_ARCH_008

The PAL shall provide a platform::Vector<T, N> type alias that stores elements in a fixed-size inline buffer. push_back(), emplace_back(), indexing, iteration, and size() shall behave like std::vector but shall never allocate from the heap.

Rationale: Protocol layers use dynamic vectors extensively; a bounded static replacement is required for no-heap builds.

Code Location: include/platform/static/containers_impl.h

Requirement: Platform String Type REQ_PAL_CONTAINER_STRING
status: implemented
priority: high
satisfies: REQ_ARCH_008

The PAL shall provide a platform::String<N> type alias that stores characters in a fixed-size inline buffer. append(), clear(), size(), c_str(), and comparison operators shall behave like std::string but shall never allocate from the heap.

Rationale: Service names, endpoint identifiers, and diagnostic strings must be representable without heap allocation in safety-critical builds.

Code Location: include/platform/static/containers_impl.h

Requirement: Platform Unordered Map Type REQ_PAL_CONTAINER_MAP
status: implemented
priority: high
satisfies: REQ_ARCH_008

The PAL shall provide a platform::UnorderedMap<K, V, N> type alias that stores entries in a fixed-size inline table. insert(), find(), erase(), and size() shall provide hash-map semantics bounded by compile-time capacity and shall never allocate from the heap.

Rationale: Session tables and subscription registries require associative lookup without runtime allocation.

Code Location: include/platform/static/containers_impl.h

Requirement: Platform Queue Type REQ_PAL_CONTAINER_QUEUE
status: implemented
priority: high
satisfies: REQ_ARCH_008

The PAL shall provide a platform::Queue<T, N> type alias that stores elements in a fixed-size ring buffer. push(), pop(), front(), empty(), and size() shall provide FIFO queue semantics and shall never allocate from the heap.

Rationale: Event dispatch and work queues require bounded FIFO storage with deterministic access time.

Code Location: include/platform/static/containers_impl.h

Requirement: Platform Function Type REQ_PAL_CONTAINER_FUNCTION
status: implemented
priority: high
satisfies: REQ_ARCH_008

The PAL shall provide a platform::Function<Sig, N> type alias that stores callables in a fixed-size inline buffer using type erasure (backed by etl::inplace_function). operator() shall invoke the stored callable with correct argument forwarding and shall never allocate from the heap.

Rationale: Callback registration (event handlers, transport hooks) must work without std::function heap allocations.

Code Location: include/platform/static/containers_impl.h

Requirement: Error - Container Capacity Exhaustion REQ_PAL_CONTAINER_CAPACITY_E01
status: implemented
priority: high
satisfies: REQ_ARCH_008

When a static container reaches its compile-time capacity, insertion operations (push_back(), push(), insert(), append()) shall fail gracefully without crashing, corrupting internal state, or allocating from the heap.

Rationale: Bounded containers must surface capacity limits to callers so protocol layers can implement safe failure modes.

Error Handling: Return false or an error indicator; container internals remain consistent. When SOMEIP_USE_STATIC_ALLOC is enabled, ETL containers are configured with ETL_THROW_EXCEPTIONS=0 and ETL_LOG_ERRORS=1; insertion failures are signaled via return codes rather than exceptions.

Code Location: include/platform/static/containers_impl.h, src/CMakeLists.txt (ETL build flags)

Buffer Pool Interface

Requirement: Buffer Pool Acquire REQ_PAL_BUFPOOL_ACQUIRE
status: implemented
priority: high

someip::platform::acquire_buffer(size) shall return a pointer to a writable byte buffer of at least size bytes from a static pool tier. The caller shall obtain exclusive use of the buffer until release_buffer() is called.

Rationale: Payload serialization and TP reassembly require transient byte buffers without heap allocation.

Code Location: include/platform/buffer_pool.h, include/platform/static/buffer_pool_impl.h

Requirement: Buffer Pool Release REQ_PAL_BUFPOOL_RELEASE
status: implemented
priority: high
satisfies: REQ_ARCH_008

someip::platform::release_buffer(ptr) shall return a previously acquired buffer to its static pool tier, making the slot available for subsequent acquisitions.

Rationale: Explicit release enables deterministic reuse of fixed pool slots and prevents pool exhaustion.

Code Location: include/platform/buffer_pool.h, include/platform/static/buffer_pool_impl.h

Requirement: Tiered Buffer Pool Selection REQ_PAL_BUFPOOL_TIERED
status: implemented
priority: high
satisfies: REQ_ARCH_008

The buffer pool shall provide multiple compile-time-configured size tiers. acquire_buffer(size) shall select the smallest tier whose slot size is greater than or equal to size.

Rationale: Tiered pools reduce memory waste while keeping allocation time bounded and predictable.

Code Location: include/platform/static/buffer_pool_impl.h, include/platform/static_config.h

Requirement: Error - Buffer Pool Exhaustion REQ_PAL_BUFPOOL_EXHAUST_E01
status: implemented
priority: high

When all slots in the matching buffer-pool tier are in use, acquire_buffer() shall return nullptr without crashing or corrupting the pool.

Rationale: Fixed pools have bounded capacity; callers must handle exhaustion the same way as message-pool exhaustion.

Error Handling: Return nullptr; pool internals remain consistent.

Code Location: include/platform/static/buffer_pool_impl.h

Requirement: Error - Buffer Pool Thread Safety REQ_PAL_BUFPOOL_THREADSAFE_E01
status: implemented
priority: high

Pool-based acquire_buffer() and release_buffer() implementations shall be thread-safe: concurrent acquisitions and releases shall not corrupt the pool or deadlock.

Rationale: Transport and SD layers acquire buffers from different threads.

Error Handling: Mutex-protected acquire/release path.

Code Location: include/platform/static/buffer_pool_impl.h, src/platform/static/buffer_pool.cpp

Static Configuration Interface

Requirement: Compile-Time Capacity Configuration REQ_PAL_STATIC_CONFIG
status: implemented
priority: high
satisfies: REQ_ARCH_008

All static-allocation capacities (message pool size, buffer-pool tier counts and slot sizes, container defaults) shall be configurable at compile time via CMake options and propagated to a generated static_config.h header.

Rationale: Integrators must size pools for their ECU memory budget without modifying library source code.

Code Location: CMakeLists.txt, include/platform/static_config.h

Requirement: Intrusive Reference Counting for Message REQ_PAL_INTRUSIVE_PTR
status: implemented
priority: high
satisfies: REQ_ARCH_008

MessagePtr shall use intrusive reference counting embedded in the Message object rather than std::shared_ptr control blocks. When the reference count reaches zero, the Message shall be returned to the static message pool.

Rationale: std::shared_ptr allocates a control block on the heap; intrusive counting enables shared ownership within a fixed pool.

Code Location: include/platform/intrusive_ptr.h, include/someip/message.h (ref_count_, intrusive_ptr_add_ref, intrusive_ptr_release)

Requirement: No-Heap Runtime Verification REQ_PAL_NOOP_HEAP_VERIFY
status: implemented
priority: high
satisfies: REQ_ARCH_008

When SOMEIP_USE_STATIC_ALLOC is enabled, the build shall link a heap-interception layer that aborts or records any call to malloc, free, new, or delete at runtime. All protocol unit tests shall pass under this interception.

Rationale: Automated verification that the no-heap policy is enforced across the entire stack, not just individual components.

Code Location: tests/no_heap_stubs.cpp, tests/test_no_heap.cpp

Static Allocation Backend

Requirement: Static Allocation Container Backend REQ_PLATFORM_STATIC_001

The static-allocation backend shall implement all PAL container types (Vector, String, UnorderedMap, Queue, Function) as type aliases over ETL containers with inline fixed-size storage and no heap fallback.

Rationale: A single backend directory provides the container implementations selected when SOMEIP_USE_STATIC_ALLOC is enabled.

Code Location: include/platform/static/containers_impl.h

Requirement: Static Message Object Pool REQ_PLATFORM_STATIC_002
status: implemented
priority: high

The static-allocation backend shall implement allocate_message() using a fixed-size pool of pre-constructed Message objects with intrusive reference counting:

  • Pool size configurable via SOMEIP_STATIC_MESSAGE_POOL_SIZE

  • alignas(Message) alignment on pool buffer

  • Returns nullptr on pool exhaustion

  • No heap allocation in alloc or release paths

Rationale: Message objects are the highest-frequency allocation in the protocol stack; a static pool eliminates heap use and fragmentation.

Code Location: include/platform/static/memory_impl.h, src/platform/static/memory.cpp

Requirement: Static Byte Buffer Pool REQ_PLATFORM_STATIC_003
status: implemented
priority: high

The static-allocation backend shall implement tiered byte-buffer pools using pre-allocated static storage:

  • Multiple tiers with compile-time slot counts and sizes

  • acquire_buffer() selects the smallest sufficient tier

  • release_buffer() returns the slot to the correct tier

  • Returns nullptr on tier exhaustion

Rationale: Payload buffers are the second-highest allocation frequency; tiered static pools balance memory efficiency and determinism.

Code Location: include/platform/static/buffer_pool_impl.h, src/platform/static/buffer_pool.cpp

Requirement: OS-Agnostic Pool Synchronization REQ_PLATFORM_STATIC_004
status: implemented
priority: high

The static-allocation backend shall protect message and buffer pools with the PAL Mutex type, making pool synchronization independent of the underlying OS threading implementation.

Rationale: Pool thread safety must work identically on host, FreeRTOS, ThreadX, and Zephyr without OS-specific locking code in pool logic.

Code Location: include/platform/static/memory_impl.h, include/platform/static/buffer_pool_impl.h

Requirement: Pimpl Static Storage REQ_PLATFORM_STATIC_005
status: implemented
priority: high
satisfies: REQ_ARCH_008

Public API classes that use the pimpl idiom shall store their implementation object in a compile-time-sized inline buffer (StaticPimpl<Impl, Size>) rather than allocating via std::make_unique or new.

Rationale: Pimpl is used throughout the stack; without static pimpl storage, enabling no-heap mode would still trigger heap allocation in constructors.

Code Location: include/platform/static/pimpl.h, public API headers using pimpl pattern

Platform Backends

POSIX/Host Backend

Requirement: POSIX/Host Threading Backend REQ_PLATFORM_POSIX_001

The POSIX/host backend shall implement the PAL threading primitives using C++ standard library types:

  • Mutexstd::mutex

  • Threadstd::thread

  • ConditionVariable → custom wrapper over std::condition_variable that accepts Mutex& (matching the RTOS API)

  • sleep_forstd::this_thread::sleep_for

Rationale: POSIX/host is the primary development and CI platform; standard library types provide zero-overhead abstractions.

Code Location: include/platform/posix/thread_impl.h, include/platform/host/host_condition_variable.h

Requirement: POSIX/Host Memory Backend REQ_PLATFORM_POSIX_002
status: implemented
priority: high

The POSIX/host backend shall implement allocate_message() using std::make_shared<Message>().

Rationale: On host/desktop, heap allocation is the natural choice; no pool is needed.

Code Location: include/platform/posix/memory_impl.h

Requirement: POSIX/Host Networking Backend REQ_PLATFORM_POSIX_003
status: implemented
priority: high

The POSIX/host backend shall provide networking through standard BSD socket headers (sys/socket.h, netinet/in.h, arpa/inet.h) and portable helpers:

  • someip_close_socket(fd)close(fd)

  • someip_shutdown_socket(fd)shutdown(fd, SHUT_RDWR)

  • someip_set_nonblocking(fd)fcntl with O_NONBLOCK

  • someip_set_blocking(fd)fcntl clearing O_NONBLOCK

Rationale: POSIX sockets are the reference networking API.

Code Location: include/platform/posix/net_impl.h

Requirement: POSIX/Host Byte-Order Backend REQ_PLATFORM_POSIX_004
status: implemented
priority: high

The POSIX/host backend shall map byte-order macros to arpa/inet.h functions:

  • someip_htonshtons

  • someip_ntohsntohs

  • someip_htonlhtonl

  • someip_ntohlntohl

Rationale: POSIX provides standard network byte-order functions.

Code Location: include/platform/posix/byteorder_impl.h

FreeRTOS Backend

Requirement: FreeRTOS Threading Backend REQ_PLATFORM_FREERTOS_001

The FreeRTOS backend shall implement the PAL threading primitives:

  • Mutex wrapping xSemaphoreCreateMutex()

  • ConditionVariable using a counting semaphore

  • Thread wrapping xTaskCreate() with binary-semaphore join support

  • sleep_for via vTaskDelay()

Rationale: FreeRTOS is one of the most widely used RTOSes in automotive embedded systems.

Code Location: include/platform/freertos/thread_impl.h

Requirement: FreeRTOS Memory Pool Backend REQ_PLATFORM_FREERTOS_002
status: implemented
priority: high

The FreeRTOS backend shall provide a static pool allocator for Message objects:

  • Fixed-size pool (configurable via SOMEIP_FREERTOS_MESSAGE_POOL_SIZE)

  • alignas(Message) alignment on pool buffer

  • Mutex-protected alloc/release

  • Returns nullptr on pool exhaustion

Rationale: Embedded targets require deterministic memory allocation without heap fragmentation.

Code Location: include/platform/freertos/memory_impl.h, src/platform/freertos/memory.cpp

ThreadX Backend

Requirement: ThreadX Threading Backend REQ_PLATFORM_THREADX_001

The ThreadX backend shall implement the PAL threading primitives:

  • Mutex wrapping TX_MUTEX with TX_INHERIT for priority inheritance

  • ConditionVariable using TX_EVENT_FLAGS_GROUP (flag bit 0)

  • Thread wrapping tx_thread_create() with static stack and join support

  • sleep_for via tx_thread_sleep()

Rationale: ThreadX (Azure RTOS) is widely used in automotive and industrial embedded systems.

Code Location: include/platform/threadx/thread_impl.h

Requirement: ThreadX Memory Pool Backend REQ_PLATFORM_THREADX_002
status: implemented
priority: high

The ThreadX backend shall provide a static pool allocator for Message objects:

  • TX_BLOCK_POOL backed by a static buffer

  • Fixed-size pool (configurable via SOMEIP_THREADX_MESSAGE_POOL_SIZE)

  • Lazy initialization guarded by TX_MUTEX

  • Returns nullptr on pool exhaustion

Rationale: Embedded targets require deterministic memory allocation without heap fragmentation.

Code Location: include/platform/threadx/memory_impl.h, src/platform/threadx/memory.cpp

lwIP Backend

Requirement: lwIP Networking Backend REQ_PLATFORM_LWIP_001
status: implemented
priority: high

The lwIP backend shall provide networking through lwIP’s socket layer:

  • Socket creation, binding, listen, accept, connect

  • UDP sendto/recvfrom and TCP send/recv

  • Non-blocking I/O via lwip_fcntl()

  • someip_close_socketlwip_close

  • someip_set_nonblocking / someip_set_blocking via lwip_fcntl

  • Conditional macro mapping when LWIP_COMPAT_SOCKETS is disabled

Rationale: lwIP is the standard TCP/IP stack for FreeRTOS and ThreadX on microcontrollers.

Code Location: include/platform/lwip/net_impl.h

Requirement: lwIP Byte-Order Backend REQ_PLATFORM_LWIP_002
status: implemented
priority: high

The lwIP backend shall map byte-order macros to lwIP definitions from lwip/def.h.

Rationale: lwIP provides its own byte-order functions optimized for the target architecture.

Code Location: include/platform/lwip/byteorder_impl.h

Zephyr Backend

Requirement: Zephyr Threading Backend REQ_PLATFORM_ZEPHYR_001

The Zephyr backend shall implement the PAL threading primitives:

  • Mutex wrapping k_mutex with k_mutex_init/k_mutex_lock/ k_mutex_unlock

  • ConditionVariable wrapping k_condvar with k_condvar_signal/ k_condvar_broadcast/k_condvar_wait

  • Thread wrapping k_thread_create with K_KERNEL_STACK_MEMBER and k_thread_join support

  • sleep_for via k_msleep with chunked conversion for durations exceeding INT32_MAX

Rationale: Zephyr is the RTOS with native SOME/IP SD multicast support used in OpenSOMEIP CI.

Code Location: include/platform/zephyr/thread_impl.h, src/platform/zephyr/thread.cpp

Requirement: Zephyr Memory Pool Backend REQ_PLATFORM_ZEPHYR_002
status: implemented
priority: high

The Zephyr backend shall provide allocate_message() and release_message() using Zephyr kernel memory primitives.

Rationale: Zephyr provides kernel-managed memory pools suitable for deterministic embedded allocation.

Code Location: include/platform/zephyr/memory_impl.h, src/platform/zephyr/memory.cpp

Requirement: Zephyr Networking Backend REQ_PLATFORM_ZEPHYR_003
status: implemented
priority: high

The Zephyr backend shall provide networking through Zephyr’s zsock_ socket API with macro mappings for standard BSD socket names:

  • socketzsock_socket, closezsock_close, etc.

  • someip_close_socketzsock_close

  • someip_set_nonblocking / someip_set_blocking via zsock_fcntl

  • inet_addr emulated via zsock_inet_pton

  • NOTE: connect is not macro-mapped to avoid clashing with ITransport::connect()

Rationale: Zephyr removed CONFIG_NET_SOCKETS_POSIX_NAMES in 4.3; explicit macros restore portability.

Code Location: include/platform/zephyr/net_impl.h

Requirement: Zephyr Byte-Order Backend REQ_PLATFORM_ZEPHYR_004
status: implemented
priority: high

The Zephyr backend shall map byte-order macros to zephyr/sys/byteorder.h functions.

Rationale: Zephyr provides endian-aware byte-order functions.

Code Location: include/platform/zephyr/byteorder_impl.h

Win32 Backend

Requirement: Win32 Threading Backend REQ_PLATFORM_WIN32_001

The Win32 backend shall implement the PAL threading primitives using C++ standard library types (identical to POSIX/host):

  • Mutexstd::mutex

  • Threadstd::thread

  • ConditionVariable → host wrapper over std::condition_variable

  • sleep_forstd::this_thread::sleep_for

Rationale: Windows support enables development on Windows workstations.

Code Location: include/platform/win32/thread_impl.h, include/platform/host/host_condition_variable.h

Requirement: Win32 Memory Backend REQ_PLATFORM_WIN32_002
status: implemented
priority: medium

The Win32 backend shall implement allocate_message() using std::make_shared<Message>().

Rationale: Desktop Windows uses standard heap allocation.

Code Location: include/platform/win32/memory_impl.h

Requirement: Win32 Networking Backend REQ_PLATFORM_WIN32_003
status: implemented
priority: medium

The Win32 backend shall provide networking through Winsock2:

  • someip_close_socket(fd)closesocket(fd)

  • someip_shutdown_socket(fd)shutdown(fd, SD_BOTH)

  • someip_set_nonblocking(fd)ioctlsocket(fd, FIONBIO, &mode)

  • Winsock2 headers and ws2_32.lib linkage

Rationale: Winsock2 is the standard networking API on Windows.

Code Location: include/platform/win32/net_impl.h

Requirement: Win32 Byte-Order Backend REQ_PLATFORM_WIN32_004
status: implemented
priority: medium

The Win32 backend shall map byte-order macros to Winsock2 functions.

Rationale: Winsock2 provides standard byte-order functions on Windows.

Code Location: include/platform/win32/byteorder_impl.h