freertos: idiomatic Zig wrappers for the FreeRTOS module#920
freertos: idiomatic Zig wrappers for the FreeRTOS module#920d-mironov wants to merge 8 commits intoZigEmbeddedGroup:mainfrom
Conversation
Lint ResultsFound 1 issue on changed lines in 1 file:
|
1983998 to
d27f423
Compare
Add config.zig with Zig error set, type aliases, and checkBaseType/ checkHandle/checkTrue helpers modeled after the network module pattern. Restructure root.zig as module hub re-exporting sub-modules, expand @cImport, add backward-compatible OS struct (deprecated), ISR exports, and stack overflow hook.
Idiomatic Zig wrapper for FreeRTOS task API covering create, destroy, delay, suspend, resume, priority get/set, scheduler control, and critical sections. Uses quoted identifiers for Zig keyword conflicts (suspend, resume). ~30 wrapped functions.
- queue.zig: Generic type-safe Queue(T) with send/receive/peek and ISR variants with proper success tracking - semaphore.zig: Binary and counting semaphores with give/take - mutex.zig: Standard and recursive mutexes with lock/unlock
- event_group.zig: Event group create/set/clear/wait bits with ISR variants - timer.zig: Software timers using xTimerGenericCommandFromTask directly (C macros incompatible with @cImport), includes destroyBlocking - notification.zig: Direct-to-task notifications using ulTaskGenericNotifyTake for correct counting-semaphore semantics
Disable configSUPPORT_PICO_SYNC_INTEROP and configSUPPORT_PICO_TIME_INTEROP in both RP2040 and RP2350_ARM configs. These use __attribute__((constructor)) which MicroZig's Cortex-M startup does not process (.init_array), causing NULL dereference. Enable configCHECK_FOR_STACK_OVERFLOW=2 for runtime detection.
Move duplicated Pico SDK glue functions (multicore, clock, spinlock, IRQ stubs) from individual examples into picosdk_stubs.c in the module. Uses C for #if PICO_RP2040 preprocessor chip detection. Follows existing picosdk_irq.c / picosdk_exception.c pattern. Update build.zig to include picosdk_stubs.c in C sources.
- Update hello_task.zig to use new API, remove inline glue code - Add queue_demo.zig: producer/consumer pattern demonstration - Add multitask_demo.zig: 4-task sensor dashboard exercising all primitives (queues, mutexes, semaphores, event groups, timers, notifications) - Register new examples in build.zig with auto-detected freertos dependency
README.md with features overview, quick start guide, full API tables for all 8 sub-modules, platform support matrix, FreeRTOSConfig.h configuration guide, known limitations, and links to examples.
d27f423 to
50cfc34
Compare
|
|
||
| /// FreeRTOS stack overflow hook — called when a task exceeds its stack. | ||
| /// Traps immediately; a debugger will stop here with a meaningful backtrace. | ||
| export fn vApplicationStackOverflowHook(_: config.TaskHandle, _: [*c]u8) void { |
There was a problem hiding this comment.
Please change to v_application_stack_overflow_hook, in MicroZig we use snake case for function names.
There was a problem hiding this comment.
vApplicationStackOverflowHook is a callback that FreeRTOS calls by name from C. The FreeRTOS kernel has a hardcoded call to vApplicationStackOverFlowHook() in its C source when it detects a stack overflow. It expects a function with that exact symbol name to exist at link time.
If renamed to v_application_overflow_hook, the C code in FreeRTOS won't find it.
|
I have currently only tested it on the RP2350 using a XIAO RP2350, but I could also implement/test on STM32, ESP32-C6/S3 and RP2040 if wanted. |
Part of #880
Builds out the FreeRTOS module with Zig wrappers for tasks, queues, semaphores, mutexes, event groups, timers, and task notifications. Error handling follows the
modules/networkpattern. The oldOSstruct is preserved as a deprecated alias.Each API group has its own file, with
root.zigas the hub.pub const cescape hatch is available.Worth noting
xTimerGenericCommandFromTaskdirectly — the C macros pass an untypedNULLthat@cImportcan't coerce.notification.take()usesulTaskGenericNotifyTake, notxTaskGenericNotifyWait(the latter doesn't decrement, breaking counting-semaphore semantics).IsrResult.successinstead of silently dropping the C return code.Note
The annoying parts of this PR were generated using AI (
[opencode](https://opencode.ai/)with Claude Opus 4.6) like some of the wrappers and documentation, but everything was reviewed by me.Bug fixes
configSUPPORT_PICO_SYNC_INTEROPandconfigSUPPORT_PICO_TIME_INTEROP— the FreeRTOS Pico port uses__attribute__((constructor))to init spinlocks, but MicroZig doesn't process.init_array, so they never run → NULL deref → Usage Fault.configCHECK_FOR_STACK_OVERFLOW=2(was 0).picosdk_stubs.c, following the existingpicosdk_irq.cpattern.Examples
hello_task(updated),queue_demo,multitask_demo— all tested on XIAO RP2350.Not in this PR
Static allocation, stream/message buffers, build-time config options, SMP, RISC-V port — tracked in #880.