Prepare the migration
Follow the Quickstart if you are new to Embedder, then open the firmware workspace. Run/init if needed and record the following in EMBEDDER.md:
- Source RTOS version, vendor SDK or fork, toolchain, and build configuration.
- Destination RTOS release, board target, required drivers, and middleware dependencies.
- Build, test, flash, and observation commands, including the connected board and probe or port.
- Application interfaces, timing tolerances, RAM, flash, and power budgets, and accepted behavior changes.
Capture the source behavior
In Act mode, ask Embedder to run the existing tests and a bounded hardware check before changing code:Review the porting plan
Run/plan and ask Embedder to trace RTOS use through the codebase, including wrappers, middleware, interrupt handlers, build variants, and generated files. The plan should identify:
- Tasks, priorities, stacks, timers, synchronization, and shared-resource ownership.
- Blocking calls, timeouts, interrupt context, and assumptions about scheduling.
- Startup, allocation, drivers, power management, and build configuration.
- Affected files, implementation order, checks for each stage, and unresolved dependencies.
Example: FreeRTOS to Zephyr
For this example, keep the existing board and migrate a sensor application with a periodic acquisition task, a sample queue, and a UART reporting task. Replace these details and limits with your project’s requirements:Establish the Zephyr application
Ask Embedder to prepare the target build using the selected Zephyr release and board target. ReviewCMakeLists.txt, prj.conf, and any board overlay, along with the workspace’s pinned dependencies. Zephyr uses Kconfig for software configuration and devicetree for hardware description; follow the selected release’s application setup.
Start with a minimal image that boots and produces console output. Then enable the sensor bus and UART, checking pins, clocks, and device readiness. Inspect the generated .config and zephyr.dts for the application image to confirm the effective configuration; a conventional single-image build places them under build/zephyr/. See Zephyr’s devicetree checks.
Review the behavior behind each API
Ask Embedder to explain each proposed replacement against the versions in your workspace:- Tasks and priorities. Move task entry points to Zephyr threads and explicitly map their relative urgency. FreeRTOS uses larger numbers for higher task priority; Zephyr uses smaller numbers, with negative values for cooperative threads and nonnegative values for preemptible threads. Include system threads in the priority review, and check time slicing and startup order. See FreeRTOS task scheduling and Zephyr threads.
- Stacks and allocation. Upstream FreeRTOS
xTaskCreatetakes a depth inStackType_telements, often called words; ESP-IDF uses bytes. Zephyr’sK_THREAD_DEFINEtakes bytes. Use Zephyr’s stack-definition or stack-allocation APIs, then measure stack usage again under load. Check heap, static allocation, and allocation-failure behavior too. See FreeRTOS task creation and Zephyr thread APIs. - Queues and synchronization. A fixed-size sample queue may fit
k_msgq. Check item size, copy versus pointer ownership, capacity, return values, and full-queue behavior. Review mutex inheritance and notification or event-bit semantics separately before choosing replacements. See Zephyr message queues. - Periods and timeouts. Preserve the acquisition task’s periodic deadline and overrun policy. Replacing a delay-until loop with a relative sleep after each iteration’s work can introduce drift. Convert tick-based waits deliberately and check rounding, no-wait, and indefinite-wait behavior against the chosen API. See Zephyr kernel timing.
- Timers and interrupt handlers. FreeRTOS software timer callbacks run in a timer service task and must not block; Zephyr timer expiry functions run in interrupt context. Defer work that needs thread context to a suitable worker or thread. Audit every
FromISRcall and critical section for the destination API’s context rules. Zephyr treats kernel API use from zero-latency interrupts as undefined behavior. See FreeRTOS software timers, Zephyr timers, and interrupt handling. - Deferred work. A shared workqueue can delay processing behind other work. Submitting the same work item while it is already queued does not retain another event. If every sample matters, preserve samples in a queue or buffer and verify the consumer’s latency. See Zephyr workqueues.
- Drivers and middleware. Decide which existing code can remain behind the application interface and which should use Zephyr drivers or subsystems. Check ownership of interrupts, clocks, DMA, and the system tick before retaining vendor HAL initialization.
Port one complete data path
After reviewing the plan, use/act and start with sensor acquisition through UART output:
Verify the migrated firmware
Build and flash the destination image on the confirmed board, then repeat the baseline tests. For the sensor example:EMBEDDER.md with the destination setup and verified commands. Record intentional behavior changes, remaining test gaps, and how to rebuild the source baseline before retiring the old RTOS configuration.
