Skip to content

Commit

Permalink
cleanups and esp-hal references (#145)
Browse files Browse the repository at this point in the history
  • Loading branch information
MabezDev authored Mar 8, 2024
1 parent 0e76579 commit fa06b86
Showing 1 changed file with 14 additions and 34 deletions.
48 changes: 14 additions & 34 deletions src/writing-your-own-application/generate-project/esp-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit fa06b86

Please sign in to comment.