debug the code to know how the executor poll the future.

The most important part is the embassy_executor::main macro. So we will focus on it.

Embassy_executor::main Macro Summary

When the main func begins to run, the #[embassy_executor::main] will :

it’s code is :

from file—embassy-executor/src/arch/cortex_m.rs:54

    pub use embassy_executor_macros::main_cortex_m as main;

and this procedural macro define here :

from file—embassy-executor-macros/src/lib.rs:72

/// Creates a new `executor` instance and declares an application entry point for Cortex-M spawning the corresponding function body as an async task.
///
/// The following restrictions apply:
///
/// * The function must accept exactly 1 parameter, an `embassy_executor::Spawner` handle that it can use to spawn additional tasks.
/// * The function must be declared `async`.
/// * The function must not use generics.
/// * Only a single `main` task may be declared.
///
/// ## Examples
/// Spawning a task:
///
/// ``` rust
/// #[embassy_executor::main]
/// async fn main(_s: embassy_executor::Spawner) {
///     // Function body
/// }
/// ```
#[proc_macro_attribute]
pub fn main_cortex_m(args: TokenStream, item: TokenStream) -> TokenStream {
    let args = syn::parse_macro_input!(args as Args);
    let f = syn::parse_macro_input!(item as syn::ItemFn);
    main::run(&args.meta, f, main::cortex_m()).unwrap_or_else(|x| x).into()
}

and the most important code is below:

from file—embassy-executor/src/arch/cortex_m.rs:99

/// This function never returns.
pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
    init(self.inner.spawner());

    loop {
        unsafe {
            self.inner.poll();
            asm!("wfe");
        };
    }
}

This is a func of the Executor.