From 60319964dbb82d0331fda3dabc237b63900fcf37 Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Wed, 28 Feb 2024 16:29:48 +0000 Subject: [PATCH] cleanups and esp-hal references --- .../generate-project/esp-template.md | 48 ++++++------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/src/writing-your-own-application/generate-project/esp-template.md b/src/writing-your-own-application/generate-project/esp-template.md index bf59239..48b4b0f 100644 --- a/src/writing-your-own-application/generate-project/esp-template.md +++ b/src/writing-your-own-application/generate-project/esp-template.md @@ -65,72 +65,52 @@ Before going further, let's see what these files are for. - `#![no_std]` - This tells the Rust compiler that this code doesn't use `libstd` - `#![no_main]` - - The `no_main` attribute says that this program won't use the standard main interface, which is tailored for command-line applications that receive arguments. Instead of the standard main, we'll use the entry attribute from the `riscv-rt` crate to define a custom entry point. In this program, we have named the entry point `main`, but any other name could have been used. The entry point function must be a [diverging function][diverging-function]. I.e. it has the signature `fn foo() -> !`; this type indicates that the function never returns – which means that the program never terminates. + - The `no_main` attribute says that this program won't use the standard main interface, which is usually used when a full operating system is available. Instead of the standard main, we'll use the entry attribute from the `esp-riscv-rt` crate to define a custom entry point. In this program, we have named the entry point `main`, but any other name could have been used. The entry point function must be a [diverging function][diverging-function]. I.e. it has the signature `fn foo() -> !`; this type indicates that the function never returns – which means that the program never terminates. ```rust,ignore 4 use esp_backtrace as _; 5 use esp_println::println; - 6 use hal::{clock::ClockControl, peripherals::Peripherals, prelude::*, timer::TimerGroup, Rtc}; + 6 use esp_hal::{clock::ClockControl, peripherals::Peripherals, prelude::*, timer::TimerGroup, Rtc}; ``` - `use esp_backtrace as _;` - Since we are in a bare-metal environment, we need a panic handler that runs if a panic occurs in code - - There are a few different crates you can use (e.g `panic-halt`) but `esp-backtrace` provides an implementation that prints the address of a backtrace - together with `espflash`/`espmonitor` these addresses can get decoded into source code locations + - There are a few different crates you can use (e.g `panic-halt`) but `esp-backtrace` provides an implementation that prints the address of a backtrace - together with `espflash` these addresses can get decoded into source code locations - `use esp_println::println;` - Provides `println!` implementation -- `use hal:{...}` +- `use esp_hal::{...}` - We need to bring in some types we are going to use - - These are from `esp-hal` ```rust,ignore 8 #[entry] 9 fn main() -> ! { 10 let peripherals = Peripherals::take(); -11 let mut system = peripherals.SYSTEM.split(); -12 let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); +11 let system = peripherals.SYSTEM.split(); +12 let clocks = ClockControl::max(system.clock_control).freeze(); 13 -14 // Disable the RTC and TIMG watchdog timers -15 let mut rtc = Rtc::new(peripherals.RTC_CNTL); -16 let timer_group0 = TimerGroup::new( -17 peripherals.TIMG0, -18 &clocks, -19 &mut system.peripheral_clock_control, -20 ); -21 let mut wdt0 = timer_group0.wdt; -22 let timer_group1 = TimerGroup::new( -23 peripherals.TIMG1, -24 &clocks, -25 &mut system.peripheral_clock_control, -26 ); -27 rtc.swd.disable(); -28 rtc.rwdt.disable(); -29 wdt0.disable(); -30 wdt1.disable(); -31 -32 println!("Hello world!"); -33 -34 loop {} -35 } +14 println!("Hello world!"); +15 +16 loop {} +17 } ``` Inside the `main` function we can find: -- `let peripherals = Peripherals::take().unwrap();` +- `let peripherals = Peripherals::take()` - HAL drivers usually take ownership of peripherals accessed via the PAC - Here we take all the peripherals from the PAC to pass them to the HAL drivers later - `let mut system = peripherals.SYSTEM.split();` - Sometimes a peripheral (here the System peripheral) is coarse-grained and doesn't exactly fit the HAL drivers - so here we split the System peripheral into smaller pieces which get passed to the drivers -- `let clocks = ClockControl::boot_defaults(system.clock_control).freeze();` - - Here we configure the system clocks - in this case, we are fine with the defaults +- `let clocks = ClockControl::max(system.clock_control).freeze();` + - Here we configure the system clocks - in this case, boost to the maxiumum for the chip - We freeze the clocks, which means we can't change them later - Some drivers need a reference to the clocks to know how to calculate rates and durations - The next block of code instantiates some peripherals (namely RTC and the two timer groups) to disable the watchdog, which is armed after boot - Without that code, the SoC would reboot after some time - - There is another way to prevent the reboot: [feeding][wtd-feeding] the watchdog + - There is another way to prevent the reboot: feeding the watchdog - `println!("Hello world!");` - Prints "Hello world!" - `loop {}` - Since our function is supposed to never return, we just "do nothing" in a loop [diverging-function]: https://doc.rust-lang.org/beta/rust-by-example/fn/diverging.html -[wtd-feeding]: https://docs.rs/esp32c3-hal/0.10.0/esp32c3_hal/prelude/trait._embedded_hal_watchdog_Watchdog.html#tymethod.feed ## Running the Code