P7(c-2) S2: cross-compile libsrt for bare-metal arm-none-eabi + boot smoke#2
Merged
Conversation
CMake toolchain (CMAKE_SYSTEM_NAME=Generic + -DGNU=ON to clear libsrt's GNU/GNU_OS detection bug) compiles libsrt's portable ::select() path (no epoll) against the FreeRTOS-Plus-POSIX pthread backend (ENABLE_STDCXX_SYNC=OFF) and lwIP sockets (LWIP_COMPAT_SOCKETS=2 -> real bare-name fns, not macros). posix-shims/ route libsrt's system includes and bridge newlib<->FreeRTOS-Plus- POSIX namespace collisions (independent of _GNU_SOURCE): syslog/uio/endian/netdb forwarders, _pthreadtypes + sys/signal (__POSIX_VISIBLE mask) + s2_prefix (timer_t) suppress newlib's POSIX types so FreeRTOS-Plus-POSIX owns them; netinet/in supplies sockaddr_in6 gap-fills. lwIP IPv6 enabled (libsrt needs the types; runtime stays IPv4). pthread_key_shim.c implements the TSD API FreeRTOS-Plus-POSIX lacks over FreeRTOS TLS slot 0. Three minimal vendor/srt portability fixes (int32_t==long on this newlib: std::min<int>, EventVariant(int32_t(0)); pthread_cancel guarded by SRT_NO_PTHREAD_CANCEL) carried as patches/0001 and applied to the pinned submodule at build time, keeping vendor/srt's git pointer pristine. libsrt.a (737 KB) cross-builds; substrate still boots under QEMU.
…r QEMU
Link libsrt.a into the firmware and run a boot smoke that initializes libsrt's
runtime on the FreeRTOS+lwIP substrate: srt_startup (spawns the SRT:GC pthread)
-> srt_create_socket -> srt_getsockstate==SRTS_INIT -> srt_close -> srt_cleanup.
New firmware glue surfaced by linking libsrt:
- atomic64_stub.c: __atomic_{load,store,exchange,fetch_add,fetch_sub,
compare_exchange}_8 via PRIMASK critical sections — Cortex-M4 has no native
64-bit atomics and the bare-metal multilib ships no libatomic.
- syscalls_stub.c: _getentropy (libsrt seeds seqnos via std::random_device ->
newlib getentropy, no bare-metal backend); deterministic, encryption is OFF.
- pthread_key_shim.c: pre-scheduler bootstrap fallback. libsrt touches its TLS
key from a global constructor before vTaskStartScheduler, where there is no
current task; vTaskSetThreadLocalStoragePointer(NULL,...) would assert
(pxCurrentTCB==NULL). Route to a global slot until the scheduler runs.
main.cpp includes srt.h at C++ linkage (it pulls C++ stdlib). RED-proven: a
fresh socket reports SRTS_INIT; flipping the expected state -> FAIL/exit 1.
R5 footprint: text 758 KB, data 4.6 KB, bss 238 KB (S1 was ~66 KB text;
libsrt + libstdc++ add ~690 KB). Resolves R4 (libsrt<->lwIP socket/select link)
and R5/R6; the SRT data plane + encryption remain S3.
There was a problem hiding this comment.
Pull request overview
Adds an S2 embedded harness that cross-compiles Haivision libsrt for bare-metal arm-none-eabi, links it against the existing FreeRTOS + lwIP substrate, and runs a QEMU mps2-an386 boot-smoke proving srt_startup → srt_create_socket → sockstate == SRTS_INIT → srt_close → srt_cleanup.
Changes:
- Introduces
embedded/s2-libsrt/firmware, build script, toolchain file, linker script, and POSIX/newlib compatibility shims needed to compile/link libsrt on Cortex-M4F. - Adds a CI step and a local script to build + run the S2 smoke test under QEMU (soft-gated with
continue-on-error+ SKIP behavior when tools are missing). - Applies a small portability patchset to the pinned
vendor/srtsubmodule at build time (without moving the git pointer).
Reviewed changes
Copilot reviewed 31 out of 32 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/check-s2-libsrt.sh | Builds and runs the S2 libsrt QEMU boot-smoke gate, with tool-presence SKIPs. |
| embedded/s2-libsrt/syscalls_stub.c | Adds bare-metal syscall stubs (notably _getentropy) to satisfy newlib/libsrt link needs. |
| embedded/s2-libsrt/sys_arch.c | Provides lwIP sys_arch FreeRTOS port used by the sockets/select path. |
| embedded/s2-libsrt/startup.c | Cortex-M4F startup + vector table wiring for FreeRTOS handlers + semihosting _exit. |
| embedded/s2-libsrt/pthread_key_shim.c | Implements minimal pthread_key_* TSD support on FreeRTOS TLS slot 0 (incl. pre-scheduler fallback). |
| embedded/s2-libsrt/posix-shims/syslog.h | Adds syslog LOG_* constants expected by libsrt headers. |
| embedded/s2-libsrt/posix-shims/sys/uio.h | Provides struct iovec inclusion via lwIP sockets. |
| embedded/s2-libsrt/posix-shims/sys/signal.h | Avoids newlib vs FreeRTOS-Plus-POSIX sigval/sigevent redefinition collisions. |
| embedded/s2-libsrt/posix-shims/sys/ioctl.h | Routes ioctl macros/decls to lwIP sockets compatibility. |
| embedded/s2-libsrt/posix-shims/sys/_pthreadtypes.h | Suppresses newlib pthread typedefs to avoid conflicts with FreeRTOS-Plus-POSIX types. |
| embedded/s2-libsrt/posix-shims/semaphore.h | Routes semaphore API to FreeRTOS-Plus-POSIX. |
| embedded/s2-libsrt/posix-shims/sched.h | Routes sched API to FreeRTOS-Plus-POSIX. |
| embedded/s2-libsrt/posix-shims/s2_prefix.h | Force-included macro sentinel overrides to prevent newlib typedef collisions. |
| embedded/s2-libsrt/posix-shims/pthread.h | Routes pthread API to FreeRTOS-Plus-POSIX and declares pthread_key_* used by libsrt. |
| embedded/s2-libsrt/posix-shims/netinet/in.h | Supplies netinet/in.h (and IPv6 bits as needed) via lwIP/compat. |
| embedded/s2-libsrt/posix-shims/netdb.h | Routes netdb to lwIP and stubs missing getnameinfo + NI_* flags. |
| embedded/s2-libsrt/posix-shims/endian.h | Provides <endian.h> macros required by libsrt’s GNU endian branch. |
| embedded/s2-libsrt/patches/0001-srt-baremetal-portability.patch | Minimal upstream-targeted portability fixes applied at build time. |
| embedded/s2-libsrt/mps2_an386.ld | Linker script for QEMU mps2-an386, including init/fini ordering + unwind tables. |
| embedded/s2-libsrt/main.cpp | Implements the S2 libsrt startup/socket/cleanup smoke test and semihosting exit. |
| embedded/s2-libsrt/lwipopts.h | lwIP configuration tuned for loopback sockets/select + libsrt compile/link needs. |
| embedded/s2-libsrt/FreeRTOSConfig.h | FreeRTOS configuration for Cortex-M4F with C++/POSIX needs enabled. |
| embedded/s2-libsrt/FreeRTOS_POSIX_portable.h | Suppresses type collisions between newlib and FreeRTOS-Plus-POSIX for this port. |
| embedded/s2-libsrt/FreeRTOS_POSIX_config.h | Placeholder for FreeRTOS-Plus-POSIX overrides (currently none). |
| embedded/s2-libsrt/clock_shim.c | Wraps clock_gettime to provide higher-resolution monotonic time. |
| embedded/s2-libsrt/build.sh | Cross-builds libsrt via CMake, builds firmware, links, and prints sizes. |
| embedded/s2-libsrt/atomic64_stub.c | Implements missing __atomic_*_8 libcalls for Cortex-M4F without libatomic. |
| embedded/s2-libsrt/arm-none-eabi.cmake | CMake toolchain file for bare-metal libsrt cross-compilation. |
| embedded/s2-libsrt/arch/sys_arch.h | lwIP arch header defining sys_arch types for FreeRTOS primitives. |
| embedded/s2-libsrt/arch/cc.h | lwIP arch header for diagnostics/assert/timeval inclusion. |
| .gitignore | Ignores S2 build artifacts (elf/o/srt-build/srt-install). |
| .github/workflows/ci.yml | Adds an S2 boot-smoke step to the no-std-baremetal job (continue-on-error). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Six code-quality fixes (none change behavior on libsrt's actual usage paths): - sys_arch.c: round byte->word stack depth up in sys_thread_new (avoid under-allocation on non-word-aligned sizes). - pthread_key_shim.c: pthread_key_create returns EINVAL on a NULL key instead of claiming the slot. - posix-shims/netdb.h: getnameinfo stub returns EAI_FAIL (POSIX contract) and clears host/serv instead of returning -1 and leaving them unset. - syscalls_stub.c: _getentropy fails cleanly (errno=EFAULT) on a NULL buffer. - lwipopts.h / posix-shims/netinet/in.h: correct stale comments that claimed IPv6 is off (it is enabled for libsrt's sockaddr_in6/ip6 types).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Sub-arc S2 of the libsrt-on-FreeRTOS arc (P7(c-2)). Cross-compiles libsrt for bare-metal
arm-none-eabiand proves its runtime initializes on the S1 FreeRTOS + lwIP substrate under QEMUmps2-an386:srt_startup→srt_create_socket→srt_getsockstate == SRTS_INIT→srt_close→srt_cleanup. RED-proven (flip the expected sockstate → FAIL/exit 1).Not a cargo crate → zero
crates/change;cargo public-apiunchanged (8 crates),#[non_exhaustive]= 258.What's here (
embedded/s2-libsrt/)arm-none-eabi.cmake):CMAKE_SYSTEM_NAME=Generic+-DGNU=ONto clear libsrt'sGNU/GNU_OSdetection bug → portable::select()path (no epoll), pthread sync backend (ENABLE_STDCXX_SYNC=OFF), logging/encryption off.posix-shims/: route libsrt's system includes (syslog,sys/uio,endian,netdb,netinet/in,sys/ioctl, …) and bridge newlib↔FreeRTOS-Plus-POSIX type collisions (pthread_*,timer_t,sigval/sigevent) — these are independent of_GNU_SOURCE(verified); fixed with sentinel guards + a__POSIX_VISIBLE-maskingsys/signal.h.pthread_key_shim.c: FreeRTOS-Plus-POSIX has nopthread_key_*(TSD); implemented over FreeRTOS TLS slot 0, with a pre-scheduler bootstrap fallback (libsrt touches its TLS key from a static-init global ctor beforevTaskStartScheduler, where there is no current task — this was the boot-smoke hang).atomic64_stub.c(__atomic_*_8via PRIMASK critical sections — no libatomic for cortex-m4f) +syscalls_stub.c(_getentropy, encryption off).patches/0001-srt-baremetal-portability.patch: three minimalvendor/srtportability fixes (int32_t==long:std::min<int>,EventVariant(int32_t(0));pthread_cancelguarded bySRT_NO_PTHREAD_CANCEL), applied to the pinned submodule at build time so thevendor/srtpointer stays pristine. Filed upstream as Fix int32_t-vs-int portability; align CThread assignment with std::thread Haivision/srt#3329.Footprint (R5)
text 758 KB / data 4.6 KB / bss 238 KB(S1 was ≈66 KB text; libsrt + libstdc++ add ~690 KB) — fits an STM32H7-class part.CI
scripts/check-s2-libsrt.shwiredcontinue-on-errorinto theno-std-baremetaljob after S1 (skips cleanly if the ARM toolchain / QEMU / cmake are absent). No new apt packages — cmake is already on the runner. Promote to hard-gate after a few green apt runs.Scope boundaries
Runtime init/teardown only — the SRT data plane (handshake/ARQ) and encryption are S3. lwIP IPv6 is enabled so libsrt's
sockaddr_in6/ip6_addr_ttypes resolve, but traffic stays IPv4.