flipperzero_rt/
lib.rs

1//! Rust Runtime for the Flipper Zero.
2//!
3//! This must be build with `-Z no-unique-section-names` to ensure that this module
4//! is linked directly into the `.text` section.
5
6#![no_std]
7#![deny(rustdoc::broken_intra_doc_links)]
8
9pub mod manifest;
10pub mod panic_handler;
11mod thread;
12
13/// The C entry point.
14///
15/// This just delegates to the user's Rust entry point.
16///
17/// # Safety
18///
19/// This should never be called manually.
20#[unsafe(no_mangle)]
21pub unsafe extern "C" fn _start(args: *mut u8) -> i32 {
22    unsafe extern "Rust" {
23        fn main(args: *mut u8) -> i32;
24    }
25
26    unsafe { main(args) }
27}
28
29/// Defines the entry point.
30///
31/// Must have the following signature: `fn(Option<&CStr>) -> i32`.
32#[macro_export]
33macro_rules! entry {
34    ($path:path) => {
35        // Force the section to `.text` instead of `.text.main`.
36        // lld seems not to automatically rename `.rel.text.main` properly.
37        #[cfg(not(miri))]
38        #[unsafe(export_name = "main")]
39        pub unsafe fn __main(args: *mut u8) -> i32 {
40            // type check the entry function
41            let f: fn(Option<&::core::ffi::CStr>) -> i32 = $path;
42
43            let args = if args.is_null() {
44                None
45            } else {
46                // SAFETY: Flipper Zero passes arguments to FAPs as a C string.
47                let args = unsafe { core::ffi::CStr::from_ptr(args.cast_const().cast()) };
48                Some(args)
49            };
50
51            let ret = f(args);
52
53            // Clean up app state.
54            $crate::__macro_support::__wait_for_thread_completion();
55
56            ret
57        }
58    };
59}
60
61#[doc(hidden)]
62pub mod __macro_support {
63    /// ⚠️ WARNING: This is *not* a stable API! ⚠️
64    ///
65    /// This function, and all code contained in the `__macro_support` module, is a
66    /// *private* API of `flipperzero-rt`. It is exposed publicly because it is used by
67    /// the `flipperzero-rt` macros, but it is not part of the stable versioned API.
68    /// Breaking changes to this module may occur in small-numbered versions without
69    /// warning.
70    pub use crate::thread::wait_for_completion as __wait_for_thread_completion;
71}