嵌入式 Rust 之书---第一章 引言

目录

*谁适合使用嵌入式Rust

*范围

*本书适用于谁

*如何使用本书

*为本书作贡献

1.1 了解你的硬件

1.2 一个no_std的Rust环境

1.3 工具

1.4 安装工具 

1.4.1 Linux

1.4.2 macOS 

1.4.3 Windows 

1.4.4 验证安装


欢迎阅读《嵌入式 Rust 之书》:关于在“裸机”嵌入式系统(如微控制器)上使用Rust编程语言的入门书。

*谁适合使用嵌入式Rust

嵌入式Rust适用于所有想要进行嵌入式编程的人,同时Rust语言提供了更高级别的概念和安全保证。(可参考《Rust编程语言》) 

*范围

本书的目标是: 

  • 让开发人员快速掌握嵌入式Rust开发。 即如何建立开发环境。
  • 分享有关使用Rust进行嵌入式开发的最新实践。 即如何最好地使用Rust语言功能来编写更正确的嵌入式软件。
  • 在某些情况下可用作参考书。例如,如何在单个项目中混合C和Rust? 

本书试图尽可能地通用,但为了使读者和作者更容易,它在所有示例中都使用了ARM Cortex-M架构。但是,本书并不假设读者熟悉这种特定的体系结构,并在需要时解释了该体系结构的特定细节。 

*本书适用于谁

本书适合具有某些嵌入式背景或某些Rust背景的人,但我们相信每个对嵌入式Rust编程感兴趣的人都可以从本书中获得一些东西。对于那些没有任何预备知识的人,我们建议您阅读“假设和先决条件”小节,了解缺失的知识,以便从书中获得更多信息并改善您的阅读体验。 您可以查看“其他资源”小节,以查找有关您可能想要了解的主题的资源。

假设和先决条件

  • 您可以使用Rust编程语言,并且可以在桌面环境中编写、运行和调试Rust应用程序。你也应该熟悉2018年版的语法,因为这本书使用的是2018版的Rust。
  • 您可以使用其他语言(如C,C ++或Ada)开发和调试嵌入式系统,并熟悉以下概念:
  1. 交叉编译
  2. 内存映射外设
  3. 中断
  4. 常见接口,如I2C,SPI,串口等。

其他资源

如果您不熟悉上述任何内容,或者如果您想了解本书中提到的特定主题的更多信息,您可能会发现其中一些资源很有用。

主题 资源 描述
Rust Rust编程语言 如果您对Rust不熟悉,我们强烈建议您阅读本书。
嵌入式,Rust 嵌入式Rust书架 在这里,您可以找到Rust的嵌入式工作组提供的其他几种资源。
嵌入式,Rust Embedonomicon 在Rust中进行嵌入式编程时的细节。
嵌入式,Rust embedded FAQ 在嵌入式上下文中有关Rust的常见问题。
中断   参考自己购买的开发板提供的文档
内存映射IO /外设   参考自己购买的开发板提供的文档
SPI, UART, RS232, USB, I2C, TTL   参考自己购买的开发板提供的文档

*如何使用本书

这本书通常假设你是从前到后阅读它。后面的章节以前面章节中的概念为基础,前面的章节可能不会深入研究某个主题的细节,在后面的章节中重新讨论该主题。本书将使用STM32F103ZET6开发板作为示例演示平台。 该板基于ARM Cortex-M架构,虽然基于此架构的大多数CPU的基本功能相同,但微控制器的外设和其他实现细节在不同供应商之间是不同的,并且通常甚至在同一供应商的微控制器系列之间也不同。

建议在学习中,根据自己的开发板情况,适当修改书中的示例!

*为本书作贡献

本书的工作在此存储库中进行协调,主要由资源团队开发。

如果您无法按照本书中的说明进行操作,或者发现本书的某些部分不够清晰或难以理解,那么这就是一个错误,应该在本书的问题跟踪器中进行报告。 

非常欢迎提交拼写错误和添加新内容的请求!

1.1 了解你的硬件

认真了解一下自己购买的开发板,翻译过程中我会使用我手上的开发板,如下图:

这块板包含什么?

  • STM32F103ZET6 芯片 
  1. 具有 64KB SRAM、512KB FLASH
  2. 2 个基本定时器、4 个通用定时器、2 个高级定时器
  3. 2 个 DMA 控制器(共 12 个通道)
  4. 3 个 SPI、 2 个 IIC、 5个串口、 1 个 USB、 1个 CAN
  5.  3 个 12 位ADC、 1 个 12 位 DAC
  6. 1 个 SDIO 接口、 1 个FSMC 接口以及 112 个通用 IO 口
  • 使用了 8 个 LED,用于基础入门学习和后续的程序调试
  • JLINK/JTAG 接口 ,用于下载及调试程序
  • 其他如图所示

1.2 一个no_std的Rust环境

 术语“嵌入式编程”用于各种不同类型的编程。从仅使用几KB的RAM和ROM对8位MCU(如ST72325xx)进行编程,到使用32/64位4核[email protected] GHz和1GB RAM的Raspberry PI(B 3+型)等系统。根据目标和用例的类型,编写代码时将应用不同的约束/限制。

有两种通用的嵌入式编程分类:

 1.主机环境

这类环境接近于正常的PC环境。这意味着您将获得一个系统接口,例如POSIX,它为您提供与各种系统(如文件系统、网络、内存管理、线程等)交互的原语。反过来,标准库通常依赖于这些原语来实现它们的功能。您可能还有某种sysroot和RAM / ROM使用限制,也许还有一些特殊的HW或I / O。总的来说,它就像是在一个特殊用途的PC环境中进行编码。

2.裸机环境

在裸机环境中,程序之前没有加载任何代码。如果没有操作系统提供的软件,我们无法加载标准库。相反,程序及其使用的crates只能使用硬件(裸机)运行。要防止Rust加载标准库,请使用no_std。标准库的平台无关部分可通过libcore获得。libcore还排除了嵌入式环境中并不总是需要的东西。其中一个是用于动态内存分配的内存分配器。如果您需要这种或任何其他功能,通常有提供这些功能的crates。

libstd运行时

如前所述,使用libstd需要某种系统集成,但这不仅是因为libstd提供了访问OS抽象的通用方法,而且还提供了运行时。除其他外,这个运行时负责设置堆栈溢出保护、处理命令行参数以及在调用程序的主函数之前生成主线程。此运行时在no_std环境中不可用。

小结

#![no_std]是一个crate-level属性,表示crate将链接到core-crate而不是std-crate。反过来,libcore crate是std crate中与平台无关的子集,它不会对程序运行的系统做出任何假设。因此,它为诸如浮点、字符串和切片之类的语言原语提供API,以及公开诸如原子操作和SIMD指令等处理器功能的API。但是,它缺少任何涉及平台集成的API。由于这些属性,no_std和libcore代码可用于任何类型的引导(阶段0)代码,如引导加载程序,固件或内核。

概述

特征 no_std std
堆(动态内存) * yes
集合(Vec,HashMap等) ** yes
栈溢出保护 no yes
在main之前运行init代码 no yes
libstd可用 no yes
libcore可用 yes yes
编写固件,内核或引导加载程序代码 yes no

 * 只有当你使用alloc crate并使用像alloc-cortex-m这样的合适的分配器时。

** 仅当您使用集合crate并配置全局默认分配器时。

1.3 工具

使用微控制器涉及几种不同的工具,因为我们将使用与您的笔记本电脑不同的架构,我们将不得不在远程设备上运行和调试程序。我们将使用下面列出的所有工具。如果未指定最低版本,任何最新版本都应该有效,但我们已经列出了我们测试过的版本。

  • Rust 1.31,1.31-beta或更新的工具链PLUS ARM Cortex-M编译支持。(安装教程
  • cargo-binutils~0.1.4
  • qemu-system-arm. 测试版本: 3.0.0
  • OpenOCD >=0.8. T测试版本: v0.9.0 and v0.10.0
  • 支持ARM的GDB。 版本7.12或更高版本强烈推荐。 经测试的版本:7.10,7.11,7.12和8.1
  • cargo-generate or git。这些工具是可选的,但可以更容易地跟随本书。

下面的文字解释了我们使用这些工具的原因。 安装说明可在下一页找到。

cargo-generate OR git

裸机程序是非标准(no_std)Rust程序,需要对链接过程进行一些调整才能使程序的内存布局正确。这需要一些额外的文件(如链接器脚本)和设置(如链接器标志)。我们已经为您打包了这些模板,您只需要填写缺少的信息(例如项目名称和目标硬件的特征)。我们的模板与 cargo-generate兼容:一个Cargo子命令,用于从模板创建新的Cargo项目。您也可以使用git,curl,wget或Web浏览器下载模板。

cargo-binutils

cargo-binutils是Cargo子命令的集合,可以方便地使用Rust工具链附带的LLVM工具。这些工具包括objdump,nm和size的LLVM版本,用于检查二进制文件。

使用这些工具优于GNU binutils的优点是:(a)安装LLVM工具使用相同的单命令安装(rustup component add llvm-tools-preview,无论您的操作系统是什么;(b)像objdump这样的工具支持rustc支持的所有体系结构 - 从ARM到x86_64  - 因为它们共享相同的LLVM后端。

qemu-system-arm

QEMU是一个模拟器。在这种情况下,我们使用可以完全模拟ARM系统的变体。我们使用QEMU在主机上运行嵌入式程序。多亏了这一点,即使您没有任何硬件,也可以按照本书的某些部分进行操作!

GDB

调试器是嵌入式开发的一个非常重要的组件,因为您可能并不总是可以将内容记录到主机控制台。在某些情况下,您的硬件上甚至可能没有指示灯闪烁!

一般来说,LLDB在调试方面与GDB一样有效但我们没有找到与GDB的load命令相对应的LLDB,后者将程序上传到目标硬件,因此目前我们建议您使用GDB。

OpenOCD

 GDB无法直接与开发板上的ST-Link调试硬件通信。它需要一个翻译器,而开放式片上调试器OpenOCD就是那个翻译器。OpenOCD是一个在笔记本电脑/ PC上运行的程序,可以在基于GDB的TCP / IP远程调试协议和ST-Link基于USB的协议之间进行转换。

OpenOCD还执行其他重要工作,作为其在开发板上调试基于ARM Cortex-M的微控制器的翻译工作:

  • 它知道如何与ARM CoreSight调试外设使用的内存映射寄存器进行交互。正是这些CoreSight寄存器允许:
  1. 断点/观察点操作
  2. 读取和写入CPU寄存器
  3. 检测CPU何时因调试事件而停止
  4. 遇到调试事件后继续执行CPU
  5. 等等
  • 它还知道如何擦除和写入微控制器的FLASH

1.4 安装工具 

此页面包含一些与工具无关的安装说明:

Rust工具链

按照https://rustup.rs上的说明安装rustup。

注意 确保编译器版本等于或高于1.31。 rustc -V应该返回比下面显示的日期更新的日期。

$ rustc -V
rustc 1.31.1 (b6c32da9b 2018-12-18)

对于带宽和磁盘使用问题,默认安装仅支持本机编译。要为ARM Cortex-M体系结构添加交叉编译支持,请选择以下编译目标之一。对于本书中用于示例的STM32F103ZET6开发板,请使用最终的thumbv7m-none-eabi目标。 

Cortex-M0,M0 +和M1(ARMv6-M架构):

$ rustup target add thumbv6m-none-eabi

Cortex-M3(ARMv7-M架构):

$ rustup target add thumbv7m-none-eabi

没有硬件浮点的Cortex-M4和M7(ARMv7E-M架构):

$ rustup target add thumbv7em-none-eabi

具有硬件浮点的Cortex-M4F和M7F(ARMv7E-M架构):

$ rustup target add thumbv7em-none-eabihf

 cargo-binutils

$ cargo install cargo-binutils

$ rustup component add llvm-tools-preview

1.4.1 Linux

以下是一些Linux发行版的安装命令。

Packages

  • Ubuntu 18.04或更新/ Debian延伸或更新

注意 gdb-multiarch是您将用于调试ARM Cortex-M程序的GDB命令

sudo apt install gdb-multiarch openocd qemu-system-arm

  • Ubuntu 14.04 and 16.04

 注意 arm-none-eabi-gdb是用于调试ARM Cortex-M程序的GDB命令

 sudo apt install gdb-arm-none-eabi openocd qemu-system-arm

  • Fedora 27或更新版本

注意 arm-none-eabi-gdb是用于调试ARM Cortex-M程序的GDB命令 

sudo dnf install arm-none-eabi-gdb openocd qemu-system-arm

  • Arch Linux

注意 arm-none-eabi-gdb是您将用于调试ARM Cortex-M程序的GDB命令

sudo pacman -S arm-none-eabi-gdb qemu-arch-extra openocd

 udev规则

此规则允许您将OpenOCD与没有root权限的Discovery板一起使用。使用下面显示的内容创建文件/etc/udev/rules.d/70-st-link.rules。

# STM32F3DISCOVERY rev A/B - ST-LINK/V2
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", TAG+="uaccess"

# STM32F3DISCOVERY rev C+ - ST-LINK/V2-1
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", TAG+="uaccess"

 然后重新加载所有udev规则:

sudo udevadm control --reload-rules

如果你把电路板插到你的笔记本上,拔下它,然后再插上。您可以通过运行以下命令来检查权限:

lsusb

应该显示出

(..)
Bus 001 Device 018: ID 0483:374b STMicroelectronics ST-LINK/V2.1
(..)

记下总线和设备号。使用这些数字创建类似/dev/bus/usb/<bus>/<device>的路径。然后像这样使用这个路径:

ls -l /dev/bus/usb/001/018

crw-------+ 1 root root 189, 17 Sep 13 12:34 /dev/bus/usb/001/018

getfacl /dev/bus/usb/001/018 | grep user

user::rw-
user:you:rw-

附加到权限的+表示存在扩展权限。getfacl命令告诉用户可以使用这个设备。

1.4.2 macOS 

可以使用Homebrew安装所有工具:

$ # GDB
$ brew install armmbed/formulae/arm-none-eabi-gcc

$ # OpenOCD
$ brew install openocd

$ # QEMU
$ brew install qemu

1.4.3 Windows 

arm-none-eabi-gdb

ARM为Windows提供.exe安装程序。从这里获取一个,按照说明操作。在安装过程完成之前勾选/选择“添加环境变量路径”选项。然后验证那些工具是否在%PATH%中:

$ arm-none-eabi-gdb -v
GNU gdb (GNU Tools for Arm Embedded Processors 7-2018-q2-update) 8.1.0.20180315-git
(..)

OpenOCD 

OpenOCD for Windows没有正式的二进制版本,但这里有非官方版本。抓取0.10.x zipfile并将其解压缩到驱动器上的某处(我建议使用C:\ OpenOCD,但使用对您有意义的驱动器号),然后更新%PATH%环境变量以包含以下路径:C:\ OpenOCD \ bin(或之前使用的路径)。使用以下命令验证OpenOCD是否在%PATH%中:

$ openocd -v
Open On-Chip Debugger 0.10.0
(..)

QEMU 

官方网站上获取QEMU。 

ST-LINK USB driver 

您还需要安装此USB驱动程序或OpenOCD将无法正常工作。按照安装程序说明操作,确保安装正确的驱动程序版本(32位或64位)。

1.4.4 验证安装

在本节中,我们将检查是否已正确安装和配置了一些必需的工具/驱动程序。根据自己开发板情况,将开发板、STLINK和电脑连接在一起,测试arn-none-eabi-gdb、STLINK驱动和openocd是否工作正常。

由于本人的试验环境为win 7 64位旗舰版系统,所以在CMD命令行中输入如下命令(在openocd的\scripts文件夹中打开命令行):

\scripts> openocd -f interface/stlink-v2-1.cfg -f target/stm32f1x.cfg

然后你会看到如下信息:

 

 接着,我们打开另外一个命令行窗口,输入如下命令,打开gdb调试器:

 在调试器中,输入如下命令:

注意gdb的连接端口号,可以在openocd的信息窗口中找到:

 

查看开发板的寄存器信息,验证连接是否成功:

到这里引言部分就结束了,基本的工具也安装好和验证过了。下一篇博文将开始学习Rust的嵌入式示例。有问题欢迎留言,一起讨论学习! 

发布了27 篇原创文章 · 获赞 18 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/drsonxu/article/details/97423630