当前位置: 首页 > news >正文

rust嵌入式开发零基础入门教程(二)

本教程的第二部分,我们将深入理解 Rust 语言的核心概念——所有权(Ownership)、借用(Borrowing)和生命周期(Lifetimes)。这些是 Rust 内存安全的基础,也是初学者理解 Rust 最关键的部分。理解它们后,我们还将探讨如何准备一块实际的开发板,为真正点亮 LED 做准备。


4. Rust 核心概念:所有权、借用和生命周期

Rust 最大的特点就是它的内存安全模型,它在编译时而不是运行时进行内存管理,从而避免了 C/C++ 中常见的内存错误,如空指针引用、数据竞争等。这主要通过三个核心概念实现:所有权、借用和生命周期

4.1 所有权 (Ownership)

所有权是 Rust 的核心特性。 每个值在 Rust 中都有一个所有者 (owner)

  • 规则 1: 每个值都有且只有一个所有者。

  • 规则 2: 当所有者超出其作用域 (scope) 时,值会被丢弃 (dropped),其内存也会被自动回收。

示例:

fn main() {let s1 = String::from("hello"); // s1 拥有 "hello" 这个字符串数据let s2 = s1; // 这里发生了“移动”(move),s1 的所有权被转移给了 s2// println!("{}", s1); // 错误!s1 已经不再拥有数据了,会报错:value borrowed here after moveprintln!("{}", s2); // 正确,s2 现在是数据的所有者
} // s2 超出作用域,"hello" 内存被释放

在嵌入式开发中,这意味着你不再需要手动调用 free()delete,也不用担心忘记释放内存而导致内存泄漏。Rust 编译器会在编译时替你处理好这一切。

4.2 借用 (Borrowing)

如果你不想转移所有权,但又需要使用某个值,该怎么办?这就是借用的作用。你可以通过引用 (&) 来借用一个值,而不是转移它的所有权。

  • 规则 1: 在任意给定时间,你只能拥有一个可变引用 (&mut T) 或任意数量的不可变引用 (&T)。

  • 规则 2: 引用必须总是有效的。

示例:

fn main() {let mut s = String::from("hello"); // s 是可变的 String// 不可变借用:可以有多个let r1 = &s; // r1 借用了 slet r2 = &s; // r2 也借用了 sprintln!("{} and {}", r1, r2); // 正确,可以同时使用多个不可变引用// s 和 r1, r2 不再被使用后,这些不可变借用结束// 可变借用:只能有一个let r3 = &mut s; // r3 可变地借用了 sr3.push_str(", world!"); // 可以通过 r3 修改 s 的值println!("{}", r3); // 正确// println!("{}", s); // 错误!当 r3 还在活跃时,不能再使用 s,因为可变借用是独占的。// 如果这里需要使用 s,r3 必须先不再被使用或超出作用域。
}

在嵌入式开发中,借用规则对于硬件寄存器访问和**共享资源(如外设)**的管理至关重要。它能防止你在同一时间对同一个寄存器进行不安全的并发修改,或者在读取的同时又尝试写入。

4.3 生命周期 (Lifetimes)

生命周期是 Rust 编译器用来确保所有借用都是有效的机制。 它们表示引用能够保持有效的作用域。

  • 规则: 引用的生命周期不能超过其所引用值的生命周期。

示例:

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {if x.len() > y.len() {x} else {y}
}fn main() {let string1 = String::from("abcd");let string2 = "xyz"; // 字面量 'static 生命周期// 这里,longest 函数返回的引用,其生命周期会是 string1 和 string2 中较短的那个。// 'a 标注确保了编译器在编译时检查引用的有效性。let result = longest(&string1, &string2);println!("The longest string is {}", result);
}

在嵌入式开发中,生命周期通常在处理外设驱动程序裸机内存区域时显得尤为重要。例如,如果你有一个引用指向某个外设寄存器,生命周期会确保这个引用在寄存器被释放或重置之前一直是有效的,从而避免访问已经不存在的内存。


5. 准备你的实际开发板

现在你对 Rust 的核心概念有了基本理解,是时候准备一块真实的微控制器板,让你的 Rust 代码在硬件上跑起来了!

5.1 选择一块开发板

对于初学者,我强烈推荐使用一个内置调试器的开发板,例如:

  • STM32 Nucleo 系列: (推荐,价格适中,资料丰富,有内置 ST-Link 调试器)

    • 例如:STM32F401RE Nucleo-64STM32F411RE Nucleo-64。它们通常基于 Cortex-M4 处理器。

  • STM32 Discovery 系列: 功能更强大,也通常内置调试器。

  • Microbit (V2): 尽管它内置调试器(DAPLink),但其 Cortex-M4F 处理器相对较小,且生态系统更偏向教育。

  • Raspberry Pi Pico: 基于 RP2040 (双 Cortex-M0+),价格非常便宜,内置调试(DAPLink)支持,生态也发展迅速。

购买建议: 如果你还没有开发板,**一块带有 ST-Link 或 DAPLink 调试器的 STM32 Nucleo/Discovery 板是一个非常好的起点。**它们可以直接通过 USB 连接到电脑进行烧录和调试,无需额外购买调试器。

5.2 安装板级工具和驱动

一旦你有了开发板,你需要安装一些工具和驱动程序,以便你的电脑能与开发板通信。

  1. 安装板级驱动:

    • ST-Link 驱动 (针对 STM32 Nucleo/Discovery): 访问 STMicroelectronics 官网,搜索并下载安装 ST-Link 驱动

      • Windows 用户通常需要安装驱动。

      • Linux 和 macOS 通常自带 libusb,但可能需要安装额外的 udev 规则来允许非 root 用户访问 USB 设备(具体请搜索 "ST-Link udev rules Linux")。

    • DAPLink / J-Link 驱动 (如果你使用 Microbit V2 或其他): DAPLink 通常是免驱动的,因为它模拟了一个 USB 大容量存储设备。J-Link 需要安装 SEGGER 提供的驱动。

  2. 安装 openocd (开放片上调试器): openocd 是一个用于调试和烧录微控制器的开源工具。

    • Linux (Debian/Ubuntu): sudo apt install openocd

    • macOS (Homebrew): brew install openocd

    • Windows: 从 OpenOCD 的 GitHub 页面或官方下载渠道获取预编译的二进制文件,并将其路径添加到系统环境变量 PATH 中。

  3. 验证 openocd 安装: 将你的开发板通过 USB 线连接到电脑,然后在终端中运行:

    openocd --version
    

    如果显示版本号,说明安装成功。要测试它是否能识别你的板子,你可以尝试运行针对你板子的配置命令(例如:openocd -f interface/stlink.cfg -f target/stm32f4x.cfg,具体配置取决于你的板子型号)。

5.3 烧录和调试工具的额外配置 (可选但推荐)

第一部分 我们安装了 probe-run,它是一个方便的工具,可以结合 openocdGDB 来直接烧录和运行 Rust 嵌入式程序。

确保 .cargo/config.toml 文件中配置了 runner。如果你使用了 cortex-m-quickstart 模板,这个文件通常已经配置好了,类似这样:

Ini, TOML

# .cargo/config.toml
[build]
target = "thumbv7em-none-eabihf" # 或者你的目标[target.thumbv7em-none-eabihf] # 或者你的目标
runner = "probe-run --chip STM32F401RETx" # 替换为你的芯片型号# 例如:STM32F411RETx, nRF52840 etc.

如何找到你的芯片型号? 通常印在微控制器芯片本体上,或者查看开发板的说明书。例如,STM32F401RE Nucleo-64 板上是 STM32F401RET6。你只需要提供前缀,例如 STM32F401RETx


下一步

现在,你已经理解了 Rust 的核心内存安全概念,并且准备好了你的实际开发板和必要的工具。

第三部分,我们将编写一个真正的嵌入式 "Hello, LED!" 程序,并将其烧录到你的开发板上,亲眼看到 Rust 代码在硬件上运行的效果!

http://www.dtcms.com/a/294710.html

相关文章:

  • 微算法科技(NASDAQ: MLGO)研究量子机器学习算法 (Quantum Machine Learning Algorithms),加速机器学习任务
  • 性能优化:Vue 3 `v-memo` 指令详解
  • 零工合规挑战:盖雅以智能安全体系重构企业用工风控
  • 漏洞扫描系列03:导出PDF/HTML报告
  • 《WebGL与Three.js打造会“讲故事“的虚拟博物馆》
  • 2.1 为什么定义tensor数据结构?
  • 宜搜科技与绿地金创考察香港数码港 共探数字科技与RWA领域战略机遇
  • 【Vue3】加载高德地图案例
  • LFU算法及优化
  • 电科金仓推出AI融合数据库,开启国产数据库新时代
  • Python 程序设计讲义(5):Python 的基本用法——数据的输入与输出
  • 【网络工程师软考版】网络互联设备、网络层协议IP和ICMP
  • Draw.io v28.0.6 中文绿色版:免费流程图制作工具
  • zabbix监控MySQL数据库
  • 如何让RAGFLow每次知识检索都是返回知识库中的所有文档?
  • HTTPS证书体系,证书加密流程(通信体系)
  • C/C++中的内存管理
  • 分布式事务中的2PC和 3PC
  • 无货源电商亚马逊采购指南:硬件隔离与支付风控实操
  • 多模态融合模型迎来新突破!
  • SAP-ABAP:SAP的MB_MIGO_BADI技术架构及增强详解
  • 代码随想录day23回溯算法2
  • 有关Kubernetes技术的学习
  • RDB和AOF的写回策略分别是什么?
  • 超表面设计参数复杂难优化?OAS光学软件专业方案来破局
  • 开源UI生态掘金:从Ant Design二次开发到行业专属组件的技术变现
  • Hexo - 免费搭建个人博客06 - 安装、切换主题Butterfly
  • C# 日期与时间 DateTime 结构和TimeSpan 结构
  • 网安-JWT
  • LLM 中的 温度怎么控制随机性的?