这是 CM Kormanyos,实时 C++:高效面向对象和模板微控制器编程,第四版(施普林格,海德堡,2021 年)ISBN 9783662629956 书的配套代码。
该存储库有几个主要部分。
ref_app
位于 ref_app。这也包括基准。GNU/GCC 交叉编译器和在Win*
上运行的各种附加工具(如下所述某些构建可选需要)可以在相关的 ckormanyos/real-time-cpp-toolchains 存储库中找到。
参考应用程序使用小型启动代码启动,随后初始化瘦微控制器抽象层 (MCAL)。然后控制权被传递到一个简单的多任务调度程序,该调度程序管理 LED 应用程序、调用循环基准测试任务并为看门狗提供服务。
LED 应用程序以以下频率切换用户 LED
参考应用程序与 C++14、17、20、23 及更高版本兼容。
应用软件只需实现一次,并在 ref_app 中的每个支持的目标上统一使用。各个目标之间的差异仅出现在与芯片特定和板特定启动/MCAL 细节相关的较低软件层中。
通过这种方式,该项目展现出高水平的可移植性。
参考应用程序支持以下目标:
目标名称(在构建命令中使用) | 目标描述 | *(面包板) |
---|---|---|
avr | MICROCHIP(R) [前 ATMEL(R)] AVR(R) ATmega328P | X |
atmega2560 | MICROCHIP(R) [前 ATMEL(R)] AVR(R) ATmega2560 | |
atmega4809 | MICROCHIP(R) [前 ATMEL(R)] AVR(R) ATmegax4809 | X |
am335x | BeagleBone 与 Texas Instruments(R) AM335x ARM(R) A8 | |
bcm2835_raspi_b | 带有 ARM1176-JZFS(TM) 的 RaspberryPi(R) 零 | |
Debug / Release | Win* 上的 PC 通过 MSVC x64 编译器Debug / Release | |
host | Win* / mingw64 / *nix 上的 PC/工作站(通过主机编译器) | |
lpc11c24 | NXP(R) OM13093 LPC11C24 板 ARM(R) Cortex(R)-M0+ | |
nxp_imxrt1062 | Teensy 4.0 板 / NXP(R) iMXRT1062 ARM(R) Cortex(R)-M7 | X |
riscvfe310 | SiFive RISC-V FE310 SoC | |
rl78 | 瑞萨(R) RL78/G13 | |
rpi_pico_rp2040 | 具有双 ARM(R) Cortex(R)-M0+ 的 RaspberryPi(R) Pico RP2040 | X |
rpi_pico2_rp2350 | 具有双 ARM(R) Cortex(R)-M33 的 RaspberryPi(R) Pico2 RP2350 | X |
rx63n | 瑞萨(R) RX630/RX631 | |
stm32f100 | 意法半导体(R) STM32F100 ARM(R) Cortex(R)-M3 | X |
stm32f407 | 意法半导体(R) STM32F407 ARM(R) Cortex(R)-M4F | |
stm32f429 | 意法半导体(R) STM32F429 ARM(R) Cortex(R)-M4F | |
stm32f446 | 意法半导体(R) STM32F446 ARM(R) Cortex(R)-M4F | |
stm32h7a3 | 意法半导体(R) STM32H7A3 ARM(R) Cortex(R)-M7 | |
stm32l100c | 意法半导体(R) STM32L100 ARM(R) Cortex(R)-M3 | X |
stm32l152 | 意法半导体(R) STM32L152 ARM(R) Cortex(R)-M3 | |
stm32l432 | 意法半导体(R) STM32L432 ARM(R) Cortex(R)-M4F | X |
v850es_fx2 | 瑞萨电子 V850es/Fx2 upd703231 | |
wch_ch32v307 | WCH CH32v307 RISC-V板 | |
wch_ch32v307_llvm | WCH CH32v307 RISC-V 板(但使用 LLVM 工具链) | |
x86_64-w64-mingw32 | 通过 GNU/GCC x86_x64 编译器运行Win* / mingw64 的 PC | |
xtensa32 | 乐鑫 (XTENSA) NodeMCU ESP32 | X |
在此表中,*(面包板)表示该板(或其某些版本)可以轻松地与普通面包板一起使用。这可能需要一些非常简单的手动焊接/安装插头引脚。
使用受支持的板之一开始参考应用程序是最简单的,例如avr
(ARDUINO) 或bcm2835_raspi_b
(RaspberryPi ZERO) 或am335x
(BeagleBoneBlack) 等。参考应用程序可以在目录 ref_app 及其子目录中找到。
参考应用程序使用交叉开发,并且构建系统受以下支持:
*nix
make 工具与 LINUX/MacOS 上的 Bash/GNUmake(bash 脚本)结合使用,Win*
上移植了*nix
式的 make 工具,Win*
,成功完成构建后,生成的工件包括 HEX 文件(例如ref_app.hex
)、映射文件、大小报告等,可在bin
目录中找到。
开始使用*nix
上的参考应用程序
target avr
)。build.sh
: ./target/build/build.sh avr rebuild
。avr rebuild
调用 GNU make,随后为target avr
重建整个解决方案。*nix
上获取它们,请运行sudo apt install gcc-avr avr-libc
。*nix
上为target avr
构建的示例我们现在将举例说明如何在*nix
中的命令 shell 上为target avr
构建参考应用程序。该目标系统基本上包括任何ARDUINO(R) 兼容板。这也是书中自制板实际使用的板兼容性。
如果需要,安装gcc-avr
。
sudo apt install gcc-avr avr-libc
克隆或获取 ckormanyos/real-time-cpp 存储库。然后构建:
cd real-time-cpp
cd ref_app
./target/build/build.sh avr rebuild
target stm32f446
在*nix
上构建的示例现在,我们将举例说明如何在*nix
中的命令 shell 上为 ARM(R) 目标构建参考应用程序。例如,考虑构建变体target stm32f446
。 STMicroElectronics(R) 的 NUCLEO-F446RE 板可以方便地用于此目的。
如果需要,安装gcc-arm-none-eabi
。
sudo apt install gcc-arm-none-eabi
克隆或获取 ckormanyos/real-time-cpp 存储库。然后构建:
cd real-time-cpp
cd ref_app
./target/build/build.sh stm32f446 rebuild
target stm32f446
构建的示例现在,我们将举例说明如何在 MacOS 的命令 shell 中为 ARM(R) 目标构建参考应用程序。例如,考虑构建变体target stm32f446
。 STMicroElectronics(R) 的 NUCLEO-F446RE 板可以方便地用于此目的。
克隆或获取 ckormanyos/real-time-cpp 存储库。
MacOS 上的 GNUmake 默认版本 3.81(现在)可以使用。此存储库中使用的 make 文件已与其兼容。有关背景信息,另请参阅第 273 期。
通过直接手动调用make
来构建目标。
cd real-time-cpp
cd ref_app
make -f target/app/make/app_make.gmk rebuild TGT=stm32f446
如果需要工具链,则必须在构建参考应用程序的目标之前安装或检索它。
如果需要,您可以通过wget
获取(或选择安装) gcc-arm-none-eabi
工具链。在这种情况下,我发现使用适用于 MacOS 的现代gcc-arm-none-eabi
很方便,可以在 Arm GNU Toolchain Downloads 中找到它。
可以通过wget
获取arm-non-eabi
工具链并在 shell 本地成功使用。如果需要,请按照以下分步过程进行操作。
步骤1:创建一个本地目录(例如macos-gnu-arm-toolchain
)并cd
进入该目录。
cd real-time-cpp
mkdir -p macos-gnu-arm-toolchain
cd macos-gnu-arm-toolchain
步骤 2:使用wget
获取工具链的 tarball,解压并将编译器的bin
目录添加到 shell 的可执行路径中。
wget --no-check-certificate https://developer.arm.com/-/media/Files/downloads/gnu/12.2.rel1/binrel/arm-gnu-toolchain-12.2.rel1-darwin-x86_64-arm-none-eabi.tar.xz
tar -xvf arm-gnu-toolchain-12.2.rel1-darwin-x86_64-arm-none-eabi.tar.xz
PATH= $( pwd ) /arm-gnu-toolchain-12.2.rel1-darwin-x86_64-arm-none-eabi/bin: $PATH
步骤 3:可选择echo
PATH
以进行快速路径检查。查询arm-non-eabi-g++
的版本也很有帮助。这有望验证工具链是否已正确添加到此 shell 的本地PATH
中。
echo $PATH
arm-none-eabi-g++ -v
现在只需使用命令通过直接调用make
来构建目标(与上面*nix
情况所示的相同)。
cd real-time-cpp
cd ref_app
make -f target/app/make/app_make.gmk rebuild TGT=stm32f446
开始使用Win*
上的参考应用程序
Win*
上运行的任何所需的 GNU/GCC 交叉编译器,如下面几段详细所述。ref_app.sln
。 Microsoft(R) VisualStudio(R) 中的ref_app
构建大量使用使用外部Makefile类型的项目工作区的交叉开发。 GNUmake 在构建过程中通过批处理文件调用。随后它与几个 Makefile 结合运行。
要为 Win32 构建除Debug
或Release
之外的任何ref_app
目标,需要交叉编译器(GNU/GCC 交叉编译器)。有关更多详细信息,请参阅下面的文字。
在Win*
上运行的 GNU/GCC 交叉编译器旨在用于 VisualStudio(R) 上的参考应用程序,可以在工具链存储库 ckormanyos/real-time-cpp-toolchains 中找到。工具链存储库包含有关安装、移动和使用这些移植的 GNU/GCC 编译器的详细说明。
有关Win*
的 GNUmake 的注意事项:可以在 ckormanyos/make-4.2.1-msvc-build 存储库中找到能够在Win*
上使用的 GNUmake。如果需要,克隆或获取此存储库的代码。使用 MSVC(即 VC 14.2 或更高版本,社区版即可)在其x64
Release
配置中构建make-4.2.1
。
跨环境CMake可以构建参考应用程序。为此,还为每个受支持的目标创建了 CMake 文件。
例如,考虑使用 CMake 为avr
目标构建参考应用程序。其模式如下所示。
cd real-time-cpp
mkdir build
cd build
cmake ../ref_app -DTRIPLE=avr -DTARGET=avr -DCMAKE_TOOLCHAIN_FILE=../ref_app/cmake/gcc-toolchain.cmake
make -j ref_app
例如,我们现在将考虑使用 CMake 为受支持的 ARM(R) 目标之一构建参考应用程序。其模式如下所示。在这种情况下,我们需要确定以下 make 选项:
-DTRIPLE=avr -DTARGET=avr
将这些选项切换为用于正在构建的基于stm32f446
ARM(R) 的目标的选项。
-DTRIPLE=arm-none-eabi -DTARGET=stm32f446
让我们完整地阐明命令,以便运行stm32f446
(即采用 Cortex(R)-M4F 的 ST Micro electronics(R) STM32F446 ARM(R))的 CMake 构建。
cd real-time-cpp
mkdir build
cd build
cmake ../ref_app -DTRIPLE=arm-none-eabi -DTARGET=stm32f446 -DCMAKE_TOOLCHAIN_FILE=../ref_app/cmake/gcc-toolchain.cmake
make -j ref_app
使用 CMake 构建其他目标时,请遵循标准*nix
模式进行构建。还可以使用 CMake 构建x86_64-w64-mingw32
或来自 MSYS、Cygwin 或任何类似*nix
的 shell 或控制台的host
也应该可以工作。
以下命令序列将在类似*nix
的 shell 或控制台上为本机host
构建。
cd real-time-cpp
mkdir build
cd build
cmake ../ref_app -DTARGET=host -DCMAKE_TOOLCHAIN_FILE=../ref_app/cmake/gcc-toolchain.cmake
make -j ref_app
还有一个适用于 ATMEL(R) AtmelStudio(R) 7 的工作区解决方案。它称为ref_app.atsln
,也位于 ref_app 目录中。参考应用程序以及每个示例都有 ATMEL Studio 项目。此存储库中的 ATMEL Studio 项目仅支持 AVR 目标。
如果您决定使用 ATMEL Studio,则不需要为这些项目使用或包含任何其他库(除了在 ATMEL Studio 标准安装期间通常安装的库)。
包括启动代码和链接器定义文件在内的目标详细信息可以在 ref_app/target 目录及其子目录中找到。每个受支持的目标微控制器系统都有单独的子目录。
称为target avr
MICROCHIP(R) [前 ATMEL(R)] AVR(R) 配置在经典的 ARDUINO(R) 兼容板上运行。该程序会切换portb.5
上的黄色 LED。
MICROCHIP(R) [前 ATMEL(R)] ATmega4809 配置称为target atmega4809
在 ARDUINO(R) EVERY 兼容板上运行,内部谐振器时钟频率为porte.2
上的黄色 LED(即D5
)。
Espressif (XTENSA) NodeMCU ESP32 实现使用 Espressif SDK 的子集来运行参考应用程序,并仅在其 1 个核心上运行单个操作系统任务。
NXP(R) OM13093 LPC11C24 板 ARM(R) Cortex(R)-M0+ 配置称为“目标 lpc11c24”,可切换port0.8
上的 LED。
ARM(R) Cortex(R)-M3 配置(称为target stm32f100
)在 ST Micro electronics(R) 出售的 STM32VL-DISCOVERY 板上运行。该程序切换portc.8
上的蓝色 LED。
第二个 ARM(R) Cortex(R)-M3 配置(称为target stm32l100c
)在 ST Micro electronics(R) 出售的 STM32L100-DISCOVERY 板上运行。该程序切换portc.8
上的蓝色 LED。
第三个 ARM(R) Cortex(R)-M3 配置(称为target stm32l152
)在 ST Micro electronics(R) 出售的 STM32L152C-DISCOVERY 板上运行。该程序切换portb.6
上的蓝色 LED。
第一个 ARM(R) Cortex(R)-M4F 配置(称为target stm32f407
)在 ST Micro electronics(R) 出售的 STM32F4-DISCOVERY 板上运行。该程序会切换portd.15
上的蓝色 LED。
另一种 ARM(R) Cortex(R)-M4F 配置(称为target stm32f446
)在 ST Micro electronics(R) 出售的 STM32F446-NUCLEO-64 板上运行。该程序会切换porta.5
上的绿色 LED。为感兴趣的人提供了该系统的臭氧调试文件。
第一个 ARM(R) Cortex(R)-M7 配置(称为target stm32h7a3
)在 ST Micro electronics(R) 出售的 STM32H7A3-NUCLEO-144 板上运行。该程序会切换portb.0
上的绿色 LED。
ARM(R) A8 配置(称为target am335x
)在 BeagleBone 板(黑色版)上运行。对于白色版本,CPU 时钟需要从*nix
发行版运行。我们的程序旨在从存储在 FAT32 SDHC 微卡上的名为MLO的原始二进制文件启动 BeagleBone。该二进制文件包括一个由两个 32 位整数组成的特殊引导标头。程序从 SD 卡加载到 RAM 内存中并随后执行。打开 BeagleBone black 时,必须在给板通电时按下启动按钮 (S2)。该程序切换第一个用户 LED( port1.21
上的 LED1)。
ARM(R) 1176-JZF-S 配置(称为target bcm2835_raspi_b
)在 RaspberryPi(R) Zero (PiZero) 单核控制器上运行。该项目为 PiZero 创建了一个裸机程序。该程序独立于板上任何类型的*nix
发行版运行。我们的程序旨在从原始二进制文件启动 PiZero。原始二进制文件称为kernel.img ,它存储在 FAT32 SDHC 微卡上。程序objcopy可用于使用输出标志-O binary
从 ELF 文件中提取原始二进制文件。 kernel.img 文件与其他三个文件一起存储在 SD 卡上:bootcode.bin、start.elf 和(可选)config.txt,所有这些都在互联网上进行了描述。此存储库中包含运行裸机参考应用程序的 SD 卡的完整 PiZero 启动内容集。该程序在 GPIO 索引0x47
处切换 GPIO 状态 LED。
rpi_pico_rp2040
目标配置采用具有双核 ARM(R) Cortex(R)-M0+ 的 RaspberryPi(R) Pico RP2040,时钟频率为Blinky_Pico_dual_core_nosdk
存储库,并取自(非常感谢)。
rpi_pico2_rp2350
目标配置采用具有双核 ARM(R) Cortex(R)-M33 的 RaspberryPi(R) Pico2 RP2350,时钟频率为2040
基本相同。同样,双核启动是由现代化的Blinky_Pico2_dual_core_nosdk
存储库中揭示的努力开创的。
目标v850es_fx2
使用经典的 Renesas(R) V850es/Fx2 内核。使用 F-Line Drive It入门套件上的 upd703231 微控制器衍生产品。
riscvfe310
目标在 Spark Fun 的商用Red Thing Plus板上使用 SiFive RISC-V FE310 SoC。端口GPIO0.5
上的蓝色 LED 已切换。
wch_ch32v307
的适配在 WCH CH32v307 板上运行。它使用南京勤恒微电子有限公司的RISC-V CH32v307微控制器。通过有线连接手动连接到端口GPIOC.0
蓝色LED1提供闪烁切换。类似的适配wch_ch32v307_llvm
本质上是相同的,只是它使用 LLVM RISC-V 工具链而不是 GCC RISC-V。
目标nxp_imxrt1062
在 Spark Fun 的 Teensy 4.0 板上运行。橙色用户 LED 已切换。
对于其他兼容板,请随时直接与我联系或提交问题,请求为您所需的目标系统提供支持。
基准测试提供了可扩展、便携的方法来识别微控制器的性能和性能等级。有关更多信息,请参阅基准测试页面上的详细信息。
该存储库中的项目使用自行编写的启动代码,以裸机、裸机模式进行无操作系统编程。除了本机 C++ 及其自己的标准库之外,不使用任何外部库。
例如,考虑 BeagleBone Black Edition(BBB,也称为target am335x
),它是此存储库中支持的几种流行目标系统之一。该板上的项目从 SD 卡上的二进制映像文件MLO启动。与此存储库中的所有其他项目一样,BBB 项目执行自己的静态初始化和芯片初始化(即,在本例中为 ARM(R) 8 AM335x 处理器的芯片初始化)。 BBB 项目在初始化之后,随后跳转到main()
它初始化am335x
MCAL 并启动我们自己编写的多任务调度程序。
下图描绘了运行中的裸机 BeagleBone Black Edition。在这种裸机运行模式下,BBB上没有运行*nix
操作系统,没有键盘、没有鼠标、没有显示器、没有调试接口、没有模拟器。
板上的微控制器正在循环执行上述基准测试之一。在多任务操作中,第一个用户 LED 在port1.21
上切换,示波器在数字 I/O port1.15
(BBB 的接头引脚P8.15
上捕获基准时间信号的实时测量结果。
构建状态徽章代表夜间 CI 构建和测试的状态。
avr-gcc
工具链仓库 ckormanyos/avr-gcc-build 为x86_64-linux-gnu
和x86_64-w64-mingw32
构建最新的avr-gcc
工具链。 Shell 和 YAML 脚本直接从 GHA 运行器上的源代码构建avr-gcc
。此外,偶尔的 GitHub 版本还为x86_64-linux-gnu
和x86_64-w64-mingw32
提供预构建的avr-gcc
工具链。
这个存储库是学习如何从源代码构建自己的avr-gcc
工具链的好地方。简单明了、描述良好的 shell 和 YAML 脚本易于理解、使用或改编。
如上所述,ckormanyos/real-time-cpp-toolchains 中描述了更详细、更广泛的嵌入式工具链。其中包括前面提到的avr-gcc
工具链以及其他工具链(有些在其他地方很难找到)。
参考应用程序和示例(以及代码片段)可以使用 GNU/GCC 编译器和 GNUmake 在*nix
上构建。假定*nix
上的 GNU/GCC 交叉编译器和 GNUmake 在标准可执行路径中可用,例如在标准 get-install 实践之后。
工具链存储库 realtime-cpp-toolchains 中提供了一些针对Win*
移植 GNU/GCC 交叉编译器。在 Microsoft(R) VisualStudio(R) 中进行开发/构建时,这些可以与参考应用程序中的微控制器解决方案配置一起使用。各种其他 GNU 工具(例如 GNUmake、SED 等)已被移植并可以在那里找到。当在Win*
上构建交叉嵌入式项目(例如ref_app
时,这些在 Makefile 中使用。
在Win*
上的参考应用程序中,Makefile 对各个工具和 GNU/GCC 工具链使用自定义的默认位置。 Win*
上的工具链默认位置是./ref_app/tools/Util/msys64/usr/local
。这个特定的工具链位置受到msys2
/ mingw64
系统的启发。
用于在Win*
上跨 MSVC/GCC 构建的工具链应位于此处。这些工具链不是此存储库的一部分,当使用受支持的Win*
版本时,或者选择将 VisualStudio(R) 项目与 CMD Batch 一起使用时,有必要单独获取这些工具链。
有关获取和使用Win*
上跨 MSVC/GCC 构建的工具链的详细说明,请参阅 realtime-cpp-toolchains 存储库。这些说明提供了在选择 Microsoft(R) VisualStudio(R) 项目(通过通常的上述 MSVC/ Win*
方式)构建参考应用程序时使用这些工具链的指导。
构建参考需要具有高水平 C++14(或更高)意识和遵守的 GNU/GCC 端口(或其他编译器),例如 GCC 5 到 13(通常越高越好)或 MSVC 14.2 或更高版本应用程序(以及示例和代码片段)。
一些代码片段不仅演示了 C++14 中的语言元素,还演示了 C++17、20、23 及更高版本的语言元素。因此,支持 C++17 甚至 C++20、23(例如 GCC 13、clang 15、MSVC 14.3 或更高版本)的编译器可能有利于所有代码片段的成功。
<chrono>
、 <ratio>
和一些内部特征标头)已获得 GNU 通用公共许可证版本 3 或更高版本的许可。