Rust嵌入式开发库esp-config的使用:专为ESP系列芯片优化的配置与管理工具

Rust嵌入式开发库esp-config的使用:专为ESP系列芯片优化的配置与管理工具

esp-config是一个为ESP系列芯片优化的Rust配置管理工具库,主要功能包括:

主要功能

  • 为布尔类型配置项生成rustc cfg标志
  • 为数值类型配置项生成环境变量(支持十进制、十六进制、八进制和二进制格式)
  • 为字符串类型配置项生成环境变量

配置查看

配置项会以Markdown表格形式输出到crate的OUT_DIR目录中,文件名为{prefix}_config_table.md。例如:

Name Description Default value
ESP_HAL_PLACE_SPI_DRIVER_IN_RAM 将SPI驱动程序放在RAM中以提高性能 false

设置配置选项

所有配置选项都会根据默认值自动设置环境变量或cfg标志。用户可以通过以下方式修改:

  1. 在本地shell中设置环境变量
  2. 使用Cargo的[env]配置节(推荐方式)

注意:由于Cargo的一个bug,任何环境变量的修改都需要完全清理重新构建项目才能生效。

最终选择的配置会输出到OUT_DIR目录的{prefix}_selected_config.md文件中。

在项目中使用配置值

esp-config提供了一系列宏来获取配置值:

// 获取数值配置
esp_config_int!(integer_type, "ENV")

// 获取字符串配置 
esp_config_str!("ENV")

// 获取布尔配置
esp_config_bool!("ENV")

对于布尔类型,还会生成去掉前缀的snake_case格式的rust cfg标志。

定义配置选项

配置选项需要在esp_config.yml文件中定义。示例:

crate: esp-bootloader-esp-idf

options:
- name: mmu_page_size
  description: ESP32-C2, ESP32-C6和ESP32-H2支持可配置的页面大小。目前仅用于填充应用程序描述符。
  default:
    - value: '"64k"'
  stability: !Stable stable-since-version
  constraints:
  - if: true
    type:
      validator: enumeration
      value:
      - 8k
      - 16k
      - 32k
      - 64k

- name: esp_idf_version
  description: 应用程序描述符中使用的ESP-IDF版本。目前引导程序不检查此版本。
  default:
    - if: 'chip == "esp32c6"'
      value: '"esp32c6"'
    - if: 'chip == "esp32"'
      value: '"other"'
  active: true

- name: partition-table-offset
  description: "分区表的地址(默认0x8000)。允许您移动分区表,为引导程序提供更多空间。注意引导程序和应用程序都需要用相同的PARTITION_TABLE_OFFSET值编译。"
  default:
    - if: true
      value: 32768
  stability: Unstable
  active: 'chip == "esp32c6"'

checks:
  - 'ESP_BOOTLOADER_ESP_IDF_CONFIG_PARTITION_TABLE_OFFSET >= 32768'

完整示例代码

// 首先在Cargo.toml中添加依赖
// [dependencies]
// esp-config = "0.5.0"

// 示例配置文件 esp_config.yml
/*
crate: my-esp-project

options:
- name: enable_debug
  description: 启用调试模式
  default:
    - value: false
  stability: !Stable stable

- name: spi_clock_speed
  description: SPI时钟速度(Hz)
  default:
    - value: 1000000
  stability: !Stable stable

- name: wifi_ssid
  description: WiFi网络SSID
  default:
    - value: '"MyESPNetwork"'
  stability: !Stable stable
*/

// 在Rust代码中使用配置
use esp_config::*;

fn main() {
    // 获取布尔配置
    const DEBUG_ENABLED: bool = esp_config_bool!("MY_ESP_PROJECT_ENABLE_DEBUG");
    
    // 获取数值配置
    const SPI_CLOCK_SPEED: u32 = esp_config_int!(u32, "MY_ESP_PROJECT_SPI_CLOCK_SPEED");
    
    // 获取字符串配置
    const WIFI_SSID: &'static str = esp_config_str!("MY_ESP_PROJECT_WIFI_SSID");
    
    println!("Debug enabled: {}", DEBUG_ENABLED);
    println!("SPI clock speed: {} Hz", SPI_CLOCK_SPEED);
    println!("WiFi SSID: {}", WIFI_SSID);
    
    // 使用cfg标志
    #[cfg(my_esp_project_enable_debug)]
    println!("Debug mode is active!");
}

许可证

esp-config采用以下两种许可证之一:

  • Apache License, Version 2.0
  • MIT license

MSRV(最低支持的Rust版本)

保证支持发布时的最新稳定Rust版本,可能支持更早版本但不做保证。


1 回复

Rust嵌入式开发库esp-config的使用指南

介绍

esp-config是一个专为ESP系列芯片优化的Rust配置与管理工具库,主要用于ESP32、ESP8266等乐鑫(Espressif)芯片的嵌入式开发。它提供了简化的配置接口和芯片管理功能,让开发者能够更高效地进行ESP芯片的固件开发和设备管理。

主要特性

  • 针对ESP系列芯片优化的配置接口
  • 统一的硬件抽象层
  • 简化的外设初始化流程
  • 内置常用功能模块(如WiFi、蓝牙等)
  • 支持no_std环境

安装方法

在Cargo.toml中添加依赖:

[dependencies]
esp-config = "0.3.0"

基本使用方法

1. 初始化芯片配置

use esp_config::prelude::*;

fn main() -> anyhow::Result<()> {
    // 初始化芯片配置
    let config = EspConfig::default()
        .with_wifi()?  // 启用WiFi功能
        .with_ble()?    // 启用BLE功能
        .with_logging(log::LevelFilter::Info)?;  // 配置日志级别
    
    // 应用配置
    let peripherals = config.setup()?;
    
    // 获取特定外设
    let wifi = peripherals.wifi();
    let ble = peripherals.ble();
    
    Ok(())
}

2. WiFi连接示例

use esp_config::prelude::*;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let config = EspConfig::default()
        .with_wifi()?
        .with_logging(log::LevelFilter::Info)?;
    
    let mut peripherals = config.setup()?;
    let wifi = peripherals.wifi();
    
    // 连接到WiFi网络
    wifi.connect("your_ssid", "your_password")
        .await?;
    
    log::info!("Connected to WiFi!");
    
    // 获取IP地址
    if let Some(ip) = wifi.get_ip().await {
        log::info!("IP Address: {}", ip);
    }
    
    Ok(())
}

3. GPIO控制示例

use esp_config::prelude::*;
use std::time::Duration;

fn main() -> anyhow::Result<()> {
    let config = EspConfig::default()
        .with_gpio()?  // 启用GPIO功能
        .with_logging(log::LevelFilter::Info)?;
    
    let peripherals = config.setup()?;
    let gpio = peripherals.gpio();
    
    // 配置GPIO2为输出
    let mut led = gpio.pin(2).into_output()?;
    
    loop {
        led.set_high()?;
        std::thread::sleep(Duration::from_secs(1));
        led.set_low()?;
        std::thread::sleep(Duration::from_secs(1));
    }
}

高级功能

1. 自定义配置

use esp_config::prelude::*;

fn main() -> anyhow::Result<()> {
    // 创建自定义配置
    let config = EspConfig::new()
        .cpu_frequency(CpuFrequency::MHz160)  // 设置CPU频率
        .wifi_config(WifiConfig {
            tx_power: 20,  // 设置WiFi发射功率(dBm)
            ..Default::default()
        })
        .ble_config(BleConfig {
            max_connections: 3,  // 设置最大BLE连接数
            ..Default::default()
        });
    
    let peripherals = config.setup()?;
    
    Ok(())
}

2. 低功耗模式

use esp_config::prelude::*;
use std::time::Duration;

fn main() -> anyhow::Result<()> {
    let config = EspConfig::default()
        .with_low_power()?  // 启用低功耗模式
        .with_logging(log::LevelFilter::Info)?;
    
    let peripherals = config.setup()?;
    let power = peripherals.power();
    
    loop {
        log::info!("Entering light sleep mode...");
        power.light_sleep(Duration::from_secs(10))?;
        log::info!("Woke up from sleep!");
    }
}

完整示例DEMO

以下是一个结合WiFi连接和GPIO控制的完整示例:

use esp_config::prelude::*;
use std::time::Duration;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // 初始化芯片配置
    let config = EspConfig::default()
        .with_wifi()?      // 启用WiFi功能
        .with_gpio()?      // 启用GPIO功能
        .with_logging(log::LevelFilter::Info)?; // 配置日志级别
    
    let mut peripherals = config.setup()?;
    let wifi = peripherals.wifi();
    let gpio = peripherals.gpio();
    
    // 配置GPIO2为输出
    let mut led = gpio.pin(2).into_output()?;
    
    // 连接到WiFi网络
    log::info!("Connecting to WiFi...");
    wifi.connect("your_ssid", "your_password").await?;
    log::info!("Connected to WiFi!");
    
    // 获取IP地址
    if let Some(ip) = wifi.get_ip().await {
        log::info!("IP Address: {}", ip);
    }
    
    // 主循环 - 闪烁LED
    loop {
        led.set_high()?;
        std::thread::sleep(Duration::from_secs(1));
        led.set_low()?;
        std::thread::sleep(Duration::from_secs(1));
    }
}

注意事项

  1. 确保使用正确的芯片目标(target)进行编译
  2. 某些功能可能需要特定的芯片型号支持
  3. 在no_std环境下使用时,需要配置合适的allocator
  4. 电源管理功能可能会影响其他外设的工作

esp-config库仍在积极开发中,建议定期检查更新以获取最新功能和改进。

回到顶部