esp-generate
简介
既然我们已经了解了如何生成一个 no_std
项目,让我们看看生成的项目里有哪些东西,
尝试理解它的各个部分,并运行它。
检查生成的项目
使用 esp-generate
创建项目时,如果不指定额外选项:
esp-generate --chip esp32c3 your-project
应该会生成类似这样的文件结构:
├── build.rs
├── .cargo
│ └── config.toml
├── Cargo.toml
├── .gitignore
├── rust-toolchain.toml
├── src
│ ├── bin
│ │ └── main.rs
│ └── lib.rs
└── .vscode
└── settings.json
在进一步讨论之前,让我们看看这些文件的用途。
build.rs
- 根据模板选项设置链接脚本参数
.cargo/config.toml
- Cargo 的配置
- 定义了一些用于正确构建项目的选项
- 包含
espflash
或probe-rs
的自定义 runner 命令。例如,runner = "espflash flash --monitor"
- 这意味着你可以直接使用cargo run
来烧写和监控你的代码
Cargo.toml
- Cargo 清单(manifest),通常声明了一些元数据和项目的依赖项
.gitignore
- 指示
git
要忽略哪些目录和文件
- 指示
rust-toolchain.toml
- 定义要使用的 Rust 工具链的种类
- 根据目标设备,工具链可以是
nightly
或esp
- 根据目标设备,工具链可以是
- 定义要使用的 Rust 工具链的种类
src/bin/main.rs
- 项目的主要源文件
- 关于它的详细信息,请参阅下面的
main.rs
简介一节
src/lib.rs
- 用于告知 Rust 编译器这段代码不使用
libstd
- 用于告知 Rust 编译器这段代码不使用
.vscode/settings.json
- 为 Visual Studio Code 定义一系列设置,使 Rust Analyzer 能够正常工作。
main.rs
简介
1 #![no_std]
2 #![no_main]
#![no_std]
- 用于告知 Rust 编译器这段代码不使用
libstd
- 用于告知 Rust 编译器这段代码不使用
#![no_main]
no_main
属性表示该程序不使用标准的 main 接口,这通常用在有完整的操作系统的情况下。我们将使用esp-riscv-rt
crate 中的入口(entry)属性来创建一个自定义入口点(entry point),而不是使用标准的 main。在此程序中,我们将入口点命名为main
,但也可以使用任何其他名称。入口点函数必须是发散函数,即具有签名fn foo() -> !
,这种类型表明该函数永远不会返回——这意味着程序永远不会终止。
4 use esp_backtrace as _;
5 use esp_hal::delay::Delay;
6 use esp_hal::prelude::*;
7 use log::info;
use esp_backtrace as _;
- 由于我们处于裸机环境中,因此需要一个 panic 处理程序,该处理程序在代码发生 panic 时运行
- 有多种不同的 crate 可选(例如
panic-halt
),但是esp-backtrace
提供了一个打印回溯地址的实现——与espflash
配合,这些地址可以被解析为源代码中的位置
use esp_hal::delay::Delay;
- 提供
Delay
驱动实现。
- 提供
use esp_hal::prelude::*;
- 导入
esp-hal
prelude。
- 导入
8 #[entry]
9 fn main() -> ! {
10 esp_println::logger::init_logger_from_env();
11
12 let delay = Delay::new();
13 loop {
14 info!("Hello world!");
15 delay.delay(500.millis());
16 }
17 }
main
函数中包含:
esp_println::logger::init_logger_from_env();
- 初始化日志记录器,如果定义了
ESP_LOG
环境变量,将使用该日志级别。
- 初始化日志记录器,如果定义了
let delay = Delay::new();
- 创建一个延迟实例。
loop {}
- 由于我们的函数应该永远不会返回,所以我们使用循环
info!("Hello world!");
- 创建一个
info
级别的日志消息,打印 "Hello world!"。
- 创建一个
delay.delay(500.millis());
- 等待 500 毫秒。
运行代码
构建和运行这段代码只需:
cargo run --release
这会根据配置构建代码,并执行 espflash
将其烧写到板子上。
由于 runner
配置还会将 --monitor
参数传递给 espflash
,屏幕上将显示打印的内容。
确保已经安装了 espflash
,否则此步骤会失败。执行此命令以安装 espflash
:
cargo install espflash
屏幕上应该会显示类似这样的内容:
...
[2024-11-14T09:29:32Z INFO ] Serial port: '/dev/ttyUSB0'
[2024-11-14T09:29:32Z INFO ] Connecting...
[2024-11-14T09:29:32Z INFO ] Using flash stub
[2024-11-14T09:29:33Z WARN ] Setting baud rate higher than 115,200 can cause issues
Chip type: esp32c3 (revision v0.3)
Crystal frequency: 40 MHz
Flash size: 4MB
Features: WiFi, BLE
MAC address: a0:76:4e:5a:d2:c8
App/part. size: 76,064/4,128,768 bytes, 1.84%
[00:00:00] [========================================] 13/13 0x0
[00:00:00] [========================================] 1/1 0x8000
[00:00:00] [========================================] 11/11 0x10000
[2024-11-14T09:29:35Z INFO ] Flashing has completed!
Commands:
CTRL+R Reset chip
CTRL+C Exit
...
INFO - Hello world!
这些是第一和第二阶段 bootloader 产生的信息,然后是我们的 “Hello world” 信息!
这就是这段代码做的事情。
可以按 CTRL+R
重启,或按 CTRL+C
退出。
如果在构建项目时遇到了什么问题,请查看 Troubleshooting 章节。