QEMU Cortex-M3 demo
The project provides a deterministic timeline-based scheduling layer for FreeRTOS applications. Tasks are configured through a static timeline, released at predefined frame times, monitored at tick resolution, and reset at every major-frame boundary.
- Target platform: QEMU Cortex-M3 (
mps2-an385) - Major frame: 100 ms in the demo configuration
- Subframes: 10 subframes, numbered from
0 - Task classes: Hard Real-Time (HRT) and Soft Real-Time (SRT)
- Configuration: static task table using
TimelineTaskConfig_t - Validation: subframe bounds, timing windows, and overlapping HRT slots
- Monitoring: UART trace with task events, idle ticks, jitter, and overhead
- Regression: automatic pass/fail checks through
make qemu_regression
include/ Scheduler headers and FreeRTOSConfig.h
src/ Timeline scheduler, task management, time base
examples/ Demo configuration, UART, startup, linker script
FreeRTOS-Kernel/ Minimal FreeRTOS subset used by the Makefile
QEMU support files are inside the
existing examples/ directory.
Install or provide these tools in PATH:
make
arm-none-eabi-gcc
qemu-system-arm
make clean
makeThe generated firmware is:
Output/timeline_scheduler_demo.elf
Run the normal demo:
make qemu_startEquivalent QEMU command:
qemu-system-arm -machine mps2-an385 -cpu cortex-m3 -kernel Output/timeline_scheduler_demo.elf -monitor none -nographic -serial stdioRun the regression build:
make qemu_regressionThis target prints the pass/fail summary once, then keeps QEMU running so the cyclic trace can be observed continuously.
Use this command for a short timeout-limited run:
make qemu_regression_onceExpected regression summary:
Test 1 - overlapping HRT rejected: PASSED
Test 2 - minimal HRT gap accepted: PASSED
Test 3 - stats API: PASSED
Test 4 - HRT activation timing: PASSED
Test 5 - HRT deadline miss termination: PASSED
Test 6 - SRT idle-time execution: PASSED
Test 7 - release jitter <= 1 tick: PASSED
Test 8 - overhead <= 10 percent: PASSED
Test 9 - idle time trace: PASSED
To exit QEMU manually:
Ctrl+A, then X
Tasks are described with TimelineTaskConfig_t.
Each task entry defines:
- task name
- task function
- task type:
TASK_TYPE_HARD_RTorTASK_TYPE_SOFT_RT - start time inside the major frame
- end time / deadline
- subframe id
- stack size
- optional task parameters
The application passes a TimelineSchedulerConfig_t to the scheduler:
xTimelineSchedulerInit(&xSchedulerConfig);
vTaskStartScheduler();Configuration can also be checked without starting the scheduler:
xTimelineSchedulerValidateConfig(&xSchedulerConfig);Runtime metrics are available through:
xTimelineSchedulerGetStats(&xStats);The demo uses:
Major frame = 100 ms
Subframes = 10 x 10 ms
Subframes are numbered from 0, so:
Subframe 0 -> 0-10 ms
Subframe 1 -> 10-20 ms
Subframe 2 -> 20-30 ms
...
Subframe 4 -> 40-50 ms
Each configured task must fit inside the subframe identified by ulSubframeId.
Invalid configurations are rejected by xTimelineSchedulerValidateConfig() and
xTimelineSchedulerInit().
HRT tasks are released at their configured start time and monitored until their deadline.
- If the task completes before the deadline, it is marked as completed.
- If the task is still running at the deadline, it is terminated.
- Release jitter is measured on HRT releases.
SRT tasks run only when no HRT task is active.
- They follow the fixed order used in the configuration array.
- They consume slack left by HRT tasks.
- They are not guaranteed to complete within the frame.
The UART trace logs:
- HRT and SRT task start times
- HRT and SRT task completion times
- HRT deadline misses and forced terminations
- major-frame reset events
- idle ticks
- maximum release jitter
- estimated scheduler overhead
- stack overflow and malloc failure hooks
Example trace:
[HRT] HRTTask1 STARTED | frame_time=21 ms | deadline=27 ms
[HRT] HRTTask1 COMPLETED | frame_time=25 ms | deadline=27 ms
[HRT] HRTTask2 STARTED | frame_time=41 ms | deadline=44 ms
[HRT] HRTTask2 DEADLINE MISSED - TERMINATING | frame_time=44 ms | deadline=44 ms
[SRT] SRTTask1 STARTED | frame_time=44 ms
[SRT] SRTTask1 COMPLETED | frame_time=46 ms
[TRACE] frame=1 idle_ticks=80 deadline_misses=1 max_jitter_ticks=0 max_overhead_permille=62
The demo timeline contains:
HRTTask1 -> start 21 ms, deadline 27 ms, subframe 2
HRTTask2 -> start 41 ms, deadline 44 ms, subframe 4
SRTTask1 -> start 44 ms, end 50 ms, subframe 4
SRTTask2 -> start 44 ms, end 50 ms, subframe 4
Expected behavior:
- HRTTask1 starts around 21 ms and completes before its 27 ms deadline.
- HRTTask2 starts around 41 ms and is terminated at its 44 ms deadline.
- SRTTask1 and SRTTask2 run only when no HRT task is active.
- The same timeline is replayed at every major-frame reset.
| Requirement | Status |
|---|---|
| Major frame and subframes | Implemented in TimelineSchedulerConfig_t |
| Static task configuration | Implemented through TimelineTaskConfig_t |
| HRT start/end timing | Implemented through start time and deadline fields |
| HRT deadline miss handling | Implemented through task termination |
| SRT idle-time execution | Implemented through slack scheduling after HRT tasks |
| Fixed SRT order | Implemented by configuration-array order |
| Periodic major-frame replay | Implemented by resetting task contexts every frame |
| Configuration validation | Implemented through xTimelineSchedulerValidateConfig() |
| Tick-level trace | Implemented through UART output |
| CPU idle monitoring | Reported as idle_ticks |
| Release jitter check | Reported as max_jitter_ticks |
| Overhead check | Reported as max_overhead_permille |
| Regression testing | Implemented through make qemu_regression |
| QEMU Cortex-M portability | Implemented through mps2-an385 build/run targets |
Every project file follows the FreeRTOS/MIT license schema through SPDX identifiers.