面向微控制器的Rust编程语言
扫描二维码
随时随地手机看文章
新编程语言的出现通常是为了弥补现有语言的不足,而这些不足通常与性能、易用性或无法支持新兴计算机科学概念有关。在嵌入式电子领域,特别是围绕微控制器的领域,Rust编程语言的出现主要是为了弥补几十年来在嵌入式系统开发领域一直稳居主导地位的C语言的诸多缺陷。
(图源:mirsad/stock.adobe.com)
C语言诞生于20世纪70年代初,缺乏当今软件开发人员所依赖的许多现代功能。下面重点列举了嵌入式系统开发中C语言的一些主要缺陷:
•包管理:Rust提供Cargo构建系统和包管理器,而C语言却没有官方的包管理解决方案。包管理支持代码重用,因为库(在Cargo中称为“crate”)可以轻松集成到新项目中。与从头开始编写代码相比,使用经过验证的现有代码库可以降低开发风险。
•更好的内存管理:Rust的内存所有权和借用系统消除了内存泄漏的风险,以及其他内存相关错误,而C语言由于依赖不太可靠的垃圾回收技术,就比较容易遇到这些风险和错误。
•并发性:Rust的所有权系统和数据结构能够实现更安全、更高效的并发性,这在嵌入式系统中至关重要。
•无空指针解引用:Rust通过对可能为空的值使用Option类型,消除了空指针解引用,而这是C语言中常见的错误原因。
•现代化数据结构:Rust支持泛型 (generic) 和特征 (trait) 等数据结构概念,提高了源代码的可维护性。
虽然C语言存在诸多缺陷,但它仍然是当今的主流语言。因此,Rust的创建者确保了这种新兴语言可以与C语言代码互操作,允许嵌入式系统开发人员在Rust应用程序中使用现有的C语言库。
Rust:从网络到微控制器
Rust是Graydon Hoare的创意,他于2006年在Mozilla工作期间就开始设计这种编程语言,作为自己的个人项目。当时他关注的是提高复杂并行计算任务的性能和可靠性,这在当时的网络浏览器中已成为一个严重问题。快进到2022年,Rust已然成为了继汇编语言和C语言之后,用于开发Linux内核的第三编程语言。
2018年,Rust用户群成立了Embedded Rust工作组,负责监督Rust轻量级版本的开发。该版本专为Arm® Cortex®-M、MSP430和RISC-V等嵌入式平台而设计。Embedded Rust开发工具可用于Windows、macOS和众多Linux发行版,当前的许多代码编辑器(如Visual Studio Code、Sublime、Atom、RustOver 和Eclipse)也支持Rust。在查看Embedded Rust的实例之前,我们先来了解几个独特概念,它们可能有助于传统软件开发人员向嵌入式系统开发过渡:
•外设访问箱 (PAC):PAC为microchip的外围设备提供直接接口。用户通常不会与PAC交互,除非他们正在为新的微控制器开发硬件抽象层,或者更高的层无法满足应用程序的需求。
•硬件抽象层 (HAL):HAL构建在芯片的PAC之上,并提供不需要深入了解芯片独特行为的抽象。通常,它们将整个外围设备抽象成一个结构(也称struct),例如可用于向片上外围设备发送数据或从其发送数据的统一结构。
•板级支持Crate (BSC):在其他嵌入式开发环境中被称为板级支持包,BSC抽象整个电路板。因此,它必须为电路板上的微控制器以及任何外围设备(如传感器和LED)创建抽象。在大多数情况下,工程师仅使用芯片的HAL,然后为外围设备编写驱动程序,或者在crate聚合站上搜索驱动程序。
STMicroelectronics电路板的实例
Rust嵌入式生态系统最关键的部分是embedded-hal Rust库,它提供了一个公共接口来使用不同微控制器平台的硬件外设。embedded-hal的目标是在为嵌入式系统开发软件时,实现代码的可移植性和可重用性。embedded-hal定义GPIO引脚、SPI、I²C、UART、定时器等常见嵌入式硬件外设的特征和抽象。这些特征提供标准化的API以便与外设交互,从而简化了可移植嵌入式代码的编写。
embedded-hal的主要优点之一是它的平台无关性。使用embedded-hal编写的代码可在各种微控制器架构和开发板上运行,无需修改,只要目标平台具备所需的特征即可。
embedded-hal除提供通用抽象外,还允许定制。如果某个微控制器或平台具有独特的功能或特性,您可以为这些功能实现embedded-hal特征,以提供一致的接口。
下面的示例展示了如何在Rust代码中使用embedded-hal:
use embedded_hal::digital::v2::{OutputPin, InputPin};
use stm32f4xx_hal::{gpio::gpioa::PA5, stm32};
fn main() {
// Initialize the microcontroller
let dp = stm32::Peripherals::take().unwrap();
let cp = cortex_m::peripheral::Peripherals::take().unwrap():
let mut rcc = dp.RCC.constrain();
let _clocks = rcc.cfgr.freeze();
// Configure a GPIO pin using embedded_hal
let gpioa = dp.GPIOA.split();
let mut led = gpioa.pa5.into_push_pull_output();
// Blink the LED
loop {
led.set_high().unwrap();
cortex_m::asm::delay(1_000_000);
led.set_low().unwrap();
cortex_m::asm::delay(1_000_000);
}
}
在本例中,我们使用embedded-hal特征(如OutputPin)来控制一个连接到GPIO引脚的LED。代码的编写方式使其可以在不同的STM32微控制器上重复使用,只要根据所需的电路板更改第二行代码即可。注意,只要平台支持GPIO引脚的embedded-hal特征并具备所需的外围设备,就没问题。
结语
Rust编程语言是为了弥补C语言的不足而设计,特别是在嵌入式系统中。凭借包管理、更好的内存管理、安全的并发和现代化的数据结构等特性,Rust比C语言有了显著改进。Rust与C语言的互操作性还允许开发人员利用现有的C语言库。Embedded Rust工作组和工具(如embedded-hal库)的创建兑现了Rust对增强嵌入式系统开发的承诺,它提供了一种不依赖平台且可定制的方法,可提高代码在不同微控制器平台之间的可移植性和可重用性。
作者简介
专业工程师Michael Parks是Green Shoe Garage的所有者。Green Shoe Garage是一家提供定制电子设计的工作室和技术咨询机构,位于马里兰州南部。Michael Parks创办了《S.T.E.A.M. Power Podcast》播客来提升公众对科技的认知。他拥有马里兰州专业工程师资质,并拥有约翰·霍普金斯大学的系统工程硕士学位。