diff --git a/README.md b/README.md index e086db0..680455b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ 这里是 https://github.com/esp-rs/book 的简体中文翻译。[直接在网页中阅读](https://narukara.github.io/rust-on-esp-book-zh-cn/) -目前进度:已经翻译完成(部分更新的内容需要重新翻译),跟踪到 4df41a5 +目前进度:已经翻译完成(部分更新的内容需要重新翻译),跟踪到 b411988 --- diff --git a/book.toml b/book.toml index a8eb183..3d5a095 100644 --- a/book.toml +++ b/book.toml @@ -12,11 +12,12 @@ git-repository-url = "https://github.com/Narukara/rust-on-esp-book-zh-cn" additional-js = ["assets/mermaid.min.js", "assets/mermaid-init.js"] [output.html.redirect] -"/overview/bare-metal.html" = "https://esp-rs.github.io/book/overview/using-the-core-library.html" -"/tooling/text-editors-and-ides.html" = "https://esp-rs.github.io/book/tooling/visual-studio-code.html" -"/debugging/vscode-debugging.html" = "https://esp-rs.github.io/book/debugging/vscode.html" -"/writing-your-own-application/no-std-applications/understanding-esp-template.html" = "https://esp-rs.github.io/book/writing-your-own-application/generate-project/esp-template.html" -"installation/installation.html" = "https://esp-rs.github.io/book/installation/index.html" +"/overview/bare-metal.html" = "https://narukara.github.io/rust-on-esp-book-zh-cn/overview/using-the-core-library.html" +"/tooling/text-editors-and-ides.html" = "https://narukara.github.io/rust-on-esp-book-zh-cn/tooling/visual-studio-code.html" +"/debugging/vscode-debugging.html" = "https://narukara.github.io/rust-on-esp-book-zh-cn/debugging/vscode.html" +"/writing-your-own-application/no-std-applications/understanding-esp-template.html" = "https://narukara.github.io/rust-on-esp-book-zh-cn/writing-your-own-application/generate-project/esp-template.html" +"installation/installation.html" = "https://narukara.github.io/rust-on-esp-book-zh-cn/installation/index.html" +"troubleshooting/espflash.html" = "https://narukara.github.io/rust-on-esp-book-zh-cn/troubleshooting/index.html" [preprocessor.mermaid] command = "mdbook-mermaid" diff --git a/src/SUMMARY.md b/src/SUMMARY.md index a314313..2f2a5fc 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -26,5 +26,4 @@ - [Wokwi](./tooling/simulating/wokwi.md) - [QEMU](tooling/simulating/qemu.md) - [Troubleshooting](./troubleshooting/index.md) - - [`esp-idf-hal` based projects](./troubleshooting/std.md) - - [`espflash`](./troubleshooting/espflash.md) + - [基于 `esp-idf-sys` 的项目](./troubleshooting/std.md) \ No newline at end of file diff --git a/src/introduction.md b/src/introduction.md index 008389a..8268d04 100644 --- a/src/introduction.md +++ b/src/introduction.md @@ -6,11 +6,14 @@ Rust 对这些设备的支持仍在不断改进中,并且进展迅速。因此,本文档的某些部分可能已经过时,或者在多次阅读之间发生了重大变化。 -对于与 Rust on ESP 相关的工具和库,请查看 GitHub 上的 [esp-rs 组织][esp-rs]。该组织由乐鑫的员工以及社区成员共同管理。 +与 Rust on ESP 相关的工具和库,请查看 GitHub 上的 [esp-rs 组织][esp-rs]。该组织由乐鑫的员工以及社区成员共同管理。 + +欢迎加入 [Matrix 上的 `esp-rs` 社区][matrix],来探讨任何技术问题!社区对所有人开放。 [rust]: https://www.rust-lang.org/ [espressif]: https://espressif.com/ [esp-rs]: https://github.com/esp-rs/ +[matrix]: https://matrix.to/#/#esp-rs:matrix.org ## 这本书适合谁 diff --git a/src/tooling/debugging/openocd.md b/src/tooling/debugging/openocd.md index 450e3d7..1f7aee8 100644 --- a/src/tooling/debugging/openocd.md +++ b/src/tooling/debugging/openocd.md @@ -74,3 +74,7 @@ OpenOCD can be used in VS Code via the [`cortex-debug`][cortex-debug] extension ``` [jtag-interfaces-esp32]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/jtag-debugging/configure-other-jtag.html + +# Debugging with Multiple Cores + +Sometimes you may need to debug each core individually in GDB or with VSCode. In this case, change `set ESP_RTOS none` to `set ESP_RTOS hwthread`. This will make each core appear as a hardware thread in GDB. This is not currently documented in Espressif official documentation but in OpenOCD docs: https://openocd.org/doc/html/GDB-and-OpenOCD.html diff --git a/src/tooling/debugging/probe-rs.md b/src/tooling/debugging/probe-rs.md index 3289cc1..1671905 100644 --- a/src/tooling/debugging/probe-rs.md +++ b/src/tooling/debugging/probe-rs.md @@ -68,14 +68,6 @@ There is a `probe-rs` extension in VS Code, see `probe-rs` [VS Code documentatio { "coreIndex": 0, "programBinary": "target/riscv32imc-unknown-none-elf/debug/${workspaceFolderBasename}", //!MODIFY - "rttEnabled": true, - "rttChannelFormats": [ - { - "channelNumber": 0, - "dataFormat": "String", - "showTimestamp": true, - } - ] } ] }, @@ -89,14 +81,6 @@ There is a `probe-rs` extension in VS Code, see `probe-rs` [VS Code documentatio { "coreIndex": 0, "programBinary": "target/riscv32imc-unknown-none-elf/debug/${workspaceFolderBasename}", //!MODIFY - "rttEnabled": true, - "rttChannelFormats": [ - { - "channelNumber": 0, - "dataFormat": "String", - "showTimestamp": true, - } - ] } ] } @@ -104,19 +88,10 @@ There is a `probe-rs` extension in VS Code, see `probe-rs` [VS Code documentatio } ``` -> ⚠️ **Note**: The example `launch.json` uses `rtt`, which may require enabling such feature in some crates, like [`esp-println`][esp-println] and [`esp-backtrace`][esp-backtrace] -> Eg: ESP32-C3 `no_std` project that uses `esp-println` and `esp-backtrace`: -> ```toml -> esp-backtrace = { version = "0.9.0", features = ["esp32c3", "panic-handler", "exception-handler", "print-rtt"] } -> esp-println = { version = "0.7.0", features = ["esp32c3", "rtt"], default-features = flase } -> ``` - The `Launch` configuration will flash the device and start debugging process while `Attach` will start the debugging in the already running application of the device. See VS Code documentation on [differences between launch and attach][vscode-configs] for more details. [probe-rs-vscode]: https://probe.rs/docs/tools/debugger/ -[esp-println]: https://github.com/esp-rs/esp-println -[esp-backtrace]: https://github.com/esp-rs/esp-backtrace?tab=readme-ov-file#features [vscode-configs]: https://code.visualstudio.com/docs/editor/debugging#_launch-versus-attach-configurations ## `cargo-flash` and `cargo-embed` diff --git a/src/tooling/simulating/qemu.md b/src/tooling/simulating/qemu.md index a35b95e..5eb40d5 100644 --- a/src/tooling/simulating/qemu.md +++ b/src/tooling/simulating/qemu.md @@ -1,12 +1,12 @@ # QEMU 乐鑫维护了一个 QEMU 的分支,位于 [espressif/QEMU][espressif-qemu],其中包含了必要的补丁,使其能够在乐鑫芯片上运行。 -请参考 [QEMU wiki][qemu-wiki] 以了解如何构建 QEMU 并使用它来仿真项目。 +请参考 [ESP 专用的 QEMU 使用指南][esp-qemu-doc] 以了解如何构建 QEMU 并使用它来仿真项目。 构建完成 QEMU 后,应该有 `qemu-system-xtensa` 文件。 [espressif-qemu]: https://github.com/espressif/qemu -[qemu-wiki]: https://github.com/espressif/qemu/wiki +[esp-qemu-doc]: https://github.com/espressif/esp-toolchain-docs/tree/main/qemu/esp32#overview ## 使用 QEMU 运行项目 @@ -20,12 +20,14 @@ cargo espflash save-image --chip esp32 --merge --release ``` 如果想使用 [`espflash`][espflash],可以先构建项目,然后生成镜像来实现相同的结果: + ```shell cargo build --release -espflash save-image --merge ESP32 target/xtensa-esp32-espidf/release/ +espflash save-image --chip ESP32 --merge target/xtensa-esp32-espidf/release/ ``` 现在,在 QEMU 中运行镜像: + ```shell /path/to/qemu-system-xtensa -nographic -machine esp32 -drive file=,if=mtd,format=raw ``` diff --git a/src/troubleshooting/espflash.md b/src/troubleshooting/espflash.md deleted file mode 100644 index dab50cd..0000000 --- a/src/troubleshooting/espflash.md +++ /dev/null @@ -1,32 +0,0 @@ -# `espflash` - -## `rtc_clk_init: Possibly invalid CONFIG_XTAL_FREQ setting` - -This issue is reported by users using an ESP32 module with a 26MHz crystal oscillator. The root -cause of the issue is that the default bootloader flashed by espflash expects a 40MHz crystal. - -### If you are building an `esp-idf-sys` based project - -Make sure your [`sdkconfig`](https://github.com/esp-rs/esp-idf-sys/blob/master/BUILD-OPTIONS.md#sdkconfig) -is set up properly to use a 26MHz crystal. It needs to contain the following configuration option: - -``` -CONFIG_XTAL_FREQ_26=y -``` - -You should also prefer using `cargo-espflash` over `espflash`. `cargo-espflash` integrates with your -project and it will flash the bootloader that is built next to your project instead of the default -one. - -If you want to use `espflash`, you need to specify an appropriate bootloader image using -`--bootloader`. You can find the bootloader in `target///build/esp-idf-sys-*/build/bootloader/bootloader.bin` - -### If you are building an `esp-hal` based project - -Make sure your HAL ([ESP32](https://docs.rs/esp32-hal/latest/esp32_hal/), [ESP32-C2](https://docs.rs/esp32c2-hal/latest/esp32c2_hal/)) -is configured to the correct crystal frequency. To do this, you must disable the default features -and enable `xtal-26mhz` (besides the other default features). - -When flashing, you need to specify an appropriate bootloader image using `--bootloader`. Currently, -you will need to build this bootloader using an `esp-idf` based project (Rust or C based should work -equally, we recommend a project set up with [esp-idf-template](https://github.com/esp-rs/esp-idf-template)). diff --git a/src/troubleshooting/index.md b/src/troubleshooting/index.md index 047819d..d4a1b85 100644 --- a/src/troubleshooting/index.md +++ b/src/troubleshooting/index.md @@ -1,6 +1,8 @@ # Troubleshooting -This chapter lists certain questions and common problems we have encountered over the time, along with their solutions. This page collects common issues independent of the chosen ESP ecosystem. +This chapter lists certain questions and common problems we have encountered over time, along with their solutions. This page collects common issues independent of the chosen ESP ecosystem. If you can't find your issue listed here, feel free to open an issue in the appropriate repository or ask on our [Matrix room][matrix]. + +[matrix]: https://matrix.to/#/#esp-rs:matrix.org ## Using the Wrong Rust Toolchain diff --git a/src/troubleshooting/std.md b/src/troubleshooting/std.md index dd5d827..b860d24 100644 --- a/src/troubleshooting/std.md +++ b/src/troubleshooting/std.md @@ -1,4 +1,22 @@ -# `esp-idf-hal` based projects +# `esp-idf-sys` based projects + +## Wrong Xtal Frequency + +Using a 26 Mhz crystal instead of a 40 MHz requires modifying the [`sdkconfig`][sdkconfig]. Add the following configuration option to your `sdkconfig` file: + +``` +CONFIG_XTAL_FREQ_26=y +``` + +After making this adjustment, execute `cargo clean` to ensure that the changes are properly incorporated into your project. See [`sdkconfig` section](#sdkconfigdefaults-file-is-updated-but-it-doesnt-appear-to-have-had-any-effect). + +When using an `esp-idf-sys` based project, you should also prefer using `cargo-espflash` instead of `espflash`. `cargo-espflash` integrates with your +project and it will flash the bootloader and partition table that is built for your project instead of the default one, see the corresponding [`cargo-espflash` readme section][cargo-espflash-bootloader]. + +If you want to use `espflash`, you can specify an appropriate bootloader and partition table using `--bootloader` and `--partition-table`. You can find the bootloader in `target///bootloader.bin` and partition table in `target///partition-table.bin` + +[sdkconfig]: https://github.com/esp-rs/esp-idf-sys/blob/master/BUILD-OPTIONS.md#sdkconfig +[cargo-espflash-bootloader]: https://github.com/esp-rs/espflash/tree/main/cargo-espflash#bootloader-and-partition-table ## Environment Variable `LIBCLANG_PATH` Not Set 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 b889dff..20ade9c 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 @@ - `#![no_std]` - 用于告知 Rust 编译器这段代码不使用 `libstd` - `#![no_main]` - - `no_main` 属性表示该程序不使用标准的 main 接口,该接口是为会接收参数的命令行应用设计的。我们将使用 `riscv-rt` crate 中的入口(entry)属性来创建一个自定义入口点(entry point),而不是使用标准的 main。在此程序中,我们将入口点命名为 `main`,但也可以使用任何其他名称。入口点函数必须是[发散函数][diverging-function],即具有签名 `fn foo() -> !`,这种类型表明该函数永远不会返回——这意味着程序永远不会终止。 + - `no_main` 属性表示该程序不使用标准的 main 接口,这通常用在有完整的操作系统的情况下。我们将使用 `esp-riscv-rt` crate 中的入口(entry)属性来创建一个自定义入口点(entry point),而不是使用标准的 main。在此程序中,我们将入口点命名为 `main`,但也可以使用任何其他名称。入口点函数必须是[发散函数][diverging-function],即具有签名 `fn foo() -> !`,这种类型表明该函数永远不会返回——这意味着程序永远不会终止。 ```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 _;` - 由于我们处于裸机环境中,因此需要一个 panic 处理程序,该处理程序在代码发生 panic 时运行 - - 有多种不同的 crate 可选(例如 `panic-halt`),但是 `esp-backtrace` 提供了一个打印回溯地址的实现——与 `espflash`/`espmonitor` 配合,这些地址可以被解析为源代码中的位置 + - 有多种不同的 crate 可选(例如 `panic-halt`),但是 `esp-backtrace` 提供了一个打印回溯地址的实现——与 `espflash` 配合,这些地址可以被解析为源代码中的位置 - `use esp_println::println;` - 提供了 `println!` 的实现 -- `use hal:{...}` +- `use esp_hal:{...}` - 我们需要导入一些类型,以待后续使用 - - 这些都是来自于 `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 // 禁用 RTC 和 TIMG 看门狗定时器 -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 } ``` `main` 函数中包含: -- `let peripherals = Peripherals::take().unwrap();` +- `let peripherals = Peripherals::take()` - HAL 驱动通常会通过 PAC(Peripheral Access Crate,外设访问 crate)获取到外设的所有权 - 这里我们从 PAC 中取出所有外设,之后将他们传递给 HAL 驱动 - `let mut system = peripherals.SYSTEM.split();` - 有时,外设(此处为 System 外设)是粗粒度的,并不完全适合 HAL 驱动——因此这里我们将 System 外设分割成更小的部分,然后传递给驱动程序 -- `let clocks = ClockControl::boot_defaults(system.clock_control).freeze();` - - 这里配置了系统时钟——本例中,使用默认值即可 +- `let clocks = ClockControl::max(system.clock_control).freeze();` + - 这里配置了系统时钟——本例中,提升到最大值 - 然后我们冻结了时钟,之后就不能再次修改它了 - 某些驱动需要一个时钟的引用,以便知道如何计算速率和时长 - 下一块代码实例化了一些外设(即 RTC 和两个定时器组)以禁用看门狗,看门狗是在上电时启用的 - 没有这段代码的话,SoC 会在一段时间后重启 - - 还有一种防止重启的方法:[喂][wtd-feeding]看门狗 + - 还有一种防止重启的方法:喂看门狗 - `println!("Hello world!");` - 打印 “Hello world!” - `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 ## 运行代码