freertos_in_rust/lib.rs
1/*
2 * FreeRTOS Kernel <DEVELOPMENT BRANCH>
3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
8 * this software and associated documentation files (the "Software"), to deal in
9 * the Software without restriction, including without limitation the rights to
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11 * the Software, and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * https://www.FreeRTOS.org
25 * https://github.com/FreeRTOS
26 *
27 * [AMENDMENT] This file is part of FreeRTOS-in-Rust, a Rust port of the FreeRTOS kernel.
28 * The original C code has been translated to Rust while preserving the original
29 * structure, control flow, and comments as much as possible.
30 */
31
32//! # FreeRTOS-in-Rust - FreeRTOS Kernel in Rust
33//!
34//! This crate provides a pure-Rust implementation of the FreeRTOS kernel,
35//! translated line-by-line from the original C source code.
36//!
37//! ## Features
38//!
39//! - `port-dummy` - Dummy port for compilation (default, panics at runtime)
40//! - `arch-32bit` - 32-bit architecture types (default)
41//! - `arch-64bit` - 64-bit architecture types
42//! - `tick-32bit` - 32-bit tick counter (default)
43//! - `tick-64bit` - 64-bit tick counter
44//! - `alloc` - Enable memory allocation via Rust's global allocator
45//! - `std` - Enable std for host testing (allocation is selected independently)
46//! - `port-test` - Deterministic host test port
47//! - `all-kernel-features` - Enable kernel capabilities without selecting a port,
48//! integer width, allocator, or SMP mode
49//! - `list-data-integrity-check` - Enable list data integrity checks
50//!
51//! Production targets must set `default-features = false` and enable exactly
52//! one hardware port. The default `port-dummy` selection is compile-only and
53//! cannot start a scheduler.
54
55#![no_std]
56#![allow(non_snake_case)]
57#![allow(non_camel_case_types)]
58#![allow(non_upper_case_globals)]
59#![allow(dead_code)] // During development
60#![allow(static_mut_refs)] // TODO: Migrate to raw pointers for Rust 2024
61
62#[cfg(not(any(
63 feature = "port-cortex-m0",
64 feature = "port-cortex-m3",
65 feature = "port-cortex-m4f",
66 feature = "port-cortex-m7",
67 feature = "port-riscv32",
68 feature = "port-cortex-a9",
69 feature = "port-cortex-a53",
70 feature = "port-test",
71 feature = "port-dummy"
72)))]
73compile_error!("select exactly one FreeRTOS-in-Rust port feature");
74
75#[cfg(any(
76 all(
77 feature = "port-cortex-m0",
78 any(
79 feature = "port-cortex-m3",
80 feature = "port-cortex-m4f",
81 feature = "port-cortex-m7",
82 feature = "port-riscv32",
83 feature = "port-cortex-a9",
84 feature = "port-cortex-a53",
85 feature = "port-test",
86 feature = "port-dummy"
87 )
88 ),
89 all(
90 feature = "port-cortex-m3",
91 any(
92 feature = "port-cortex-m4f",
93 feature = "port-cortex-m7",
94 feature = "port-riscv32",
95 feature = "port-cortex-a9",
96 feature = "port-cortex-a53",
97 feature = "port-test",
98 feature = "port-dummy"
99 )
100 ),
101 all(
102 feature = "port-cortex-m4f",
103 any(
104 feature = "port-cortex-m7",
105 feature = "port-riscv32",
106 feature = "port-cortex-a9",
107 feature = "port-cortex-a53",
108 feature = "port-test",
109 feature = "port-dummy"
110 )
111 ),
112 all(
113 feature = "port-cortex-m7",
114 any(
115 feature = "port-riscv32",
116 feature = "port-cortex-a9",
117 feature = "port-cortex-a53",
118 feature = "port-test",
119 feature = "port-dummy"
120 )
121 ),
122 all(
123 feature = "port-riscv32",
124 any(
125 feature = "port-cortex-a9",
126 feature = "port-cortex-a53",
127 feature = "port-test",
128 feature = "port-dummy"
129 )
130 ),
131 all(
132 feature = "port-cortex-a9",
133 any(
134 feature = "port-cortex-a53",
135 feature = "port-test",
136 feature = "port-dummy"
137 )
138 ),
139 all(
140 feature = "port-cortex-a53",
141 any(feature = "port-test", feature = "port-dummy")
142 ),
143 all(feature = "port-test", feature = "port-dummy")
144))]
145compile_error!("FreeRTOS-in-Rust port features are mutually exclusive");
146
147#[cfg(any(
148 all(feature = "heap-4", feature = "heap-5"),
149 all(feature = "heap-4", feature = "alloc"),
150 all(feature = "heap-5", feature = "alloc")
151))]
152compile_error!("allocator features are mutually exclusive");
153
154#[cfg(feature = "std")]
155extern crate std;
156
157#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
158extern crate alloc;
159
160// Core modules
161pub mod config;
162pub mod trace;
163pub mod types;
164
165// Port layer
166pub mod port;
167
168// Memory management
169pub mod memory;
170
171// Kernel modules
172pub mod kernel;
173
174// Safe synchronization wrappers. Individual capabilities such as Mutex,
175// streams, and timers retain their own feature gates.
176pub mod sync;
177
178// Re-export commonly used items at crate root (like FreeRTOS.h does)
179pub use config::*;
180pub use types::*;
181
182// =============================================================================
183// Convenience Functions
184// =============================================================================
185
186/// Delays the current task for the specified number of ticks.
187///
188/// This is a safe wrapper around `vTaskDelay`. The context capability prevents
189/// task-only delay operations from being called through an ISR or timer
190/// callback API.
191#[inline]
192pub fn delay(context: &sync::TaskContext, ticks: TickType_t) {
193 assert!(context.current().is_some(), "delay requires a running task");
194 sync::assert_can_block("delay", ticks);
195 // Safety: TaskContext and the checks above establish a live current task,
196 // running scheduler, task context, and an unsuspended blocking path.
197 unsafe { kernel::tasks::vTaskDelay(ticks) };
198}
199
200/// Delays the current task for the specified number of milliseconds.
201///
202/// Converts milliseconds to ticks using the configured tick rate without
203/// narrowing the millisecond value first.
204///
205/// # Panics
206///
207/// Panics when the requested duration cannot be represented by `TickType_t`.
208/// Use [`milliseconds_to_ticks_checked`] when the duration is not known to fit.
209#[inline]
210pub fn delay_ms(context: &sync::TaskContext, ms: u32) {
211 let ticks = milliseconds_to_ticks_checked(u64::from(ms))
212 .expect("millisecond delay does not fit in TickType_t");
213 delay(context, ticks);
214}
215
216/// Starts the FreeRTOS scheduler.
217///
218/// This function does not return under normal operation. Tasks must be
219/// created before calling this function.
220#[inline]
221pub fn start_scheduler(_context: sync::TaskContext) -> ! {
222 sync::assert_task_context("start_scheduler");
223 assert_eq!(
224 kernel::tasks::xTaskGetSchedulerState(),
225 kernel::tasks::taskSCHEDULER_NOT_STARTED,
226 "start_scheduler requires exclusive pre-scheduler initialization context"
227 );
228 // Safety: consuming the non-sendable startup capability establishes the
229 // crate's exclusive pre-scheduler entry boundary, and the unconditional
230 // state check rejects a TaskContext obtained from a running task. Internal
231 // task creation failures are handled by the raw scheduler path before it
232 // returns.
233 unsafe { kernel::tasks::vTaskStartScheduler() };
234 // vTaskStartScheduler only returns if creating an internal task failed.
235 panic!("FreeRTOS scheduler failed to start")
236}