From b48fcd9229b40800cc96ff3157d8b36057dc2047 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Fri, 10 Dec 2021 12:04:12 +0100 Subject: Add more content --- docs/modules/ROOT/pages/basic_application.adoc | 75 ++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 docs/modules/ROOT/pages/basic_application.adoc (limited to 'docs/modules/ROOT/pages/basic_application.adoc') diff --git a/docs/modules/ROOT/pages/basic_application.adoc b/docs/modules/ROOT/pages/basic_application.adoc new file mode 100644 index 000000000..d56cb5e1d --- /dev/null +++ b/docs/modules/ROOT/pages/basic_application.adoc @@ -0,0 +1,75 @@ += A basic Embassy application + +So you've got one of the xref:examples.adoc[examples] running, but what now? Let's go through a simple Embassy application for the nRF52 DK to understand it better. + + +== The Cargo.toml + +== The main + +=== Rust Nightly + +The first thing you'll notice is a few declarations stating that Embassy requires some nightly features: + +[source,rust] +---- +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] +---- + +=== Dealing with errors + +Then, what follows are some declarations on how to deal with panics and faults. During development, a good practice is to rely on `defmt-rtt` and `panic-probe` to print diagnostics to the terminal: + +[source,rust] +---- +use defmt_rtt as _; +use panic_probe as _; +---- + +=== Task declaration + +After a bit of import declaration, the tasks run by the application should be declared: + +[source,rust] +---- +#[embassy::task] +async fn blinker(led: Output<'static, P0_13>, interval: Duration) { + loop { + let _ = led.set_high(); + Timer::after(interval).await; + let _ = led.set_low(); + Timer::after(interval).await; + } +} +---- + +An embassy task must be declared `async`, and may NOT take generic arguments. In this case, we are handed the LED that should be blinked and the interval of the blinking. + +NOTE: Notice that there is not busy waiting going on in this task. It is using the Embassy timer to yield execution, allowing the microcontroller to sleep in between the blinking. + +=== Main + +The main entry point of an Embassy application is defined using the `#[embassy::main]` macro. The entry point is also required to take a `Spawner` and a `Peripherals` argument. + +The `Spawner` is the way the main application spawns other tasks. The `Peripherals` type holds all peripherals that the application may use. In this case, we want to configure one of the pins as a GPIO output driving the LED: + +[source, rust] +---- +#[embassy::main] +async fn main(spawner: Spawner, p: Peripherals) { + let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard); + let _ = spawner.spawn(blinker(led, Duration::from_millis(300))); +} +---- + + +What happens when the `blinker` task have been spawned and main returns? Well, the main entry point is actually just like any other task, except that you can only have one and it takes some specific type arguments. The magic lies within the `#[embassy::main]` macro. The macro does the following: + +. Creates an Embassy Executor instance +. Initializes the microcontroller to get the `Peripherals` +. Defines a main task for the entry point +. Runs the executor spawning the main task + +There is also a way to run the executor without using the macro, in which case you have to create the `Executor` instance yourself. -- cgit From e93f2679b1edbedd83e09fbc3b7a07dbf1ef80a4 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Fri, 10 Dec 2021 12:27:44 +0100 Subject: More content --- docs/modules/ROOT/pages/basic_application.adoc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'docs/modules/ROOT/pages/basic_application.adoc') diff --git a/docs/modules/ROOT/pages/basic_application.adoc b/docs/modules/ROOT/pages/basic_application.adoc index d56cb5e1d..53aaa3d7d 100644 --- a/docs/modules/ROOT/pages/basic_application.adoc +++ b/docs/modules/ROOT/pages/basic_application.adoc @@ -3,8 +3,6 @@ So you've got one of the xref:examples.adoc[examples] running, but what now? Let's go through a simple Embassy application for the nRF52 DK to understand it better. -== The Cargo.toml - == The main === Rust Nightly @@ -73,3 +71,16 @@ What happens when the `blinker` task have been spawned and main returns? Well, t . Runs the executor spawning the main task There is also a way to run the executor without using the macro, in which case you have to create the `Executor` instance yourself. + +== The Cargo.toml + +The project definition needs to contain the embassy dependencies: + +[source,toml] +---- +include::example$examples/nrf/Cargo.toml[lines="9..11"] +---- + +Depending on your microcontroller, you may need to replace `embassy-nrf` with something else (`embassy-stm32` for STM32. Remember to update feature flags as well). + +In this particular case, the nrf52840 chip is selected, and the RTC1 peripheral is used as the time driver. -- cgit From e5d4d0952b78ef343f14205f5ebd3f1d7804f9e8 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Fri, 10 Dec 2021 12:46:41 +0100 Subject: Add doc-specific example and add it to CI --- docs/modules/ROOT/pages/basic_application.adoc | 30 +++++++------------------- 1 file changed, 8 insertions(+), 22 deletions(-) (limited to 'docs/modules/ROOT/pages/basic_application.adoc') diff --git a/docs/modules/ROOT/pages/basic_application.adoc b/docs/modules/ROOT/pages/basic_application.adoc index 53aaa3d7d..c2849927a 100644 --- a/docs/modules/ROOT/pages/basic_application.adoc +++ b/docs/modules/ROOT/pages/basic_application.adoc @@ -2,8 +2,9 @@ So you've got one of the xref:examples.adoc[examples] running, but what now? Let's go through a simple Embassy application for the nRF52 DK to understand it better. +== Main -== The main +The full example can be found link:https://github.com/embassy-rs/embassy/tree/book-poc/docs/modules/ROOT/examples/basic[here]. === Rust Nightly @@ -11,9 +12,7 @@ The first thing you'll notice is a few declarations stating that Embassy require [source,rust] ---- -#![no_std] -#![no_main] -#![feature(type_alias_impl_trait)] +include::example$basic/src/main.rs[lines="1..3"] ---- === Dealing with errors @@ -22,8 +21,7 @@ Then, what follows are some declarations on how to deal with panics and faults. [source,rust] ---- -use defmt_rtt as _; -use panic_probe as _; +include::example$basic/src/main.rs[lines="5..6"] ---- === Task declaration @@ -32,15 +30,7 @@ After a bit of import declaration, the tasks run by the application should be de [source,rust] ---- -#[embassy::task] -async fn blinker(led: Output<'static, P0_13>, interval: Duration) { - loop { - let _ = led.set_high(); - Timer::after(interval).await; - let _ = led.set_low(); - Timer::after(interval).await; - } -} +include::example$basic/src/main.rs[lines="16..24"] ---- An embassy task must be declared `async`, and may NOT take generic arguments. In this case, we are handed the LED that should be blinked and the interval of the blinking. @@ -53,13 +43,9 @@ The main entry point of an Embassy application is defined using the `#[embassy:: The `Spawner` is the way the main application spawns other tasks. The `Peripherals` type holds all peripherals that the application may use. In this case, we want to configure one of the pins as a GPIO output driving the LED: -[source, rust] +[source,rust] ---- -#[embassy::main] -async fn main(spawner: Spawner, p: Peripherals) { - let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard); - let _ = spawner.spawn(blinker(led, Duration::from_millis(300))); -} +include::example$basic/src/main.rs[lines="26..30"] ---- @@ -78,7 +64,7 @@ The project definition needs to contain the embassy dependencies: [source,toml] ---- -include::example$examples/nrf/Cargo.toml[lines="9..11"] +include::example$basic/Cargo.toml[lines="8..10"] ---- Depending on your microcontroller, you may need to replace `embassy-nrf` with something else (`embassy-stm32` for STM32. Remember to update feature flags as well). -- cgit From aa0abe976a481b0fb58d6bdee5d448658e6f8ffc Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Fri, 10 Dec 2021 12:58:23 +0100 Subject: Fix doc example compile --- docs/modules/ROOT/pages/basic_application.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/modules/ROOT/pages/basic_application.adoc') diff --git a/docs/modules/ROOT/pages/basic_application.adoc b/docs/modules/ROOT/pages/basic_application.adoc index c2849927a..46a375c86 100644 --- a/docs/modules/ROOT/pages/basic_application.adoc +++ b/docs/modules/ROOT/pages/basic_application.adoc @@ -30,7 +30,7 @@ After a bit of import declaration, the tasks run by the application should be de [source,rust] ---- -include::example$basic/src/main.rs[lines="16..24"] +include::example$basic/src/main.rs[lines="18..27"] ---- An embassy task must be declared `async`, and may NOT take generic arguments. In this case, we are handed the LED that should be blinked and the interval of the blinking. @@ -45,7 +45,7 @@ The `Spawner` is the way the main application spawns other tasks. The `Periphera [source,rust] ---- -include::example$basic/src/main.rs[lines="26..30"] +include::example$basic/src/main.rs[lines="28..-1"] ---- @@ -64,7 +64,7 @@ The project definition needs to contain the embassy dependencies: [source,toml] ---- -include::example$basic/Cargo.toml[lines="8..10"] +include::example$basic/Cargo.toml[lines="8..9"] ---- Depending on your microcontroller, you may need to replace `embassy-nrf` with something else (`embassy-stm32` for STM32. Remember to update feature flags as well). -- cgit