Ohhnews

分类导航

$ cd ..
Jetbrains Blog原文

在 CLion 中开发基于 Arm TrustZone 的 STM32 项目

#stm32#clion#arm trustzone#嵌入式开发#调试

Arm v8-M 架构引入了一种称为 TrustZone 的安全扩展,它将在微控制器(MCU)上运行的固件分为两个世界:安全和非安全。在这篇博文中,我想讨论如何使用这项技术有效地处理 STM32 项目。我们将帮助您完成所有设置,以便在 CLion 中使用最新、最优秀的代码分析工具进行常规调试。

我们将使用以下设置:

我们还需要安装:

  • STM32CubeProgrammer 用于配置硬件。
  • STM32CubeCLT 1.20.0,其中包含捆绑的 ST-Link _gdbserver 和交叉编译器,用于构建和调试 STM32 固件。

您可以在 GitHub 上找到我们将作为演示使用的项目。最初的存根由 STM32CubeMX 6.16.0 生成。如果您想跟着操作,可以使用稍旧版本的 CLion;最低要求的版本是 2025.3.2。

理解基于 STM32 TrustZone 的项目结构

安全的 TrustZone 模式是一种特权模式,可以服务于非特权非安全模式的请求。我们为什么要使用这个?原因类似于我们在老式台式机上有用户空间的原因——我们不完全信任某些代码,不希望它干扰关键任务。关键任务部分进入安全模式,而某些用户、无线、远程或互联网数据的处理在非安全模式下运行。因此,我们将重要的内容与暴露的接口(如 Wi-Fi 或蓝牙)隔离开来。

[LOADING...]

即使互联网连接的代码中存在漏洞,重要的核心也不会受到影响。例如,即使设备的非安全应用程序代码被攻破,安全引导加载程序 也允许远程重新刷写新的、修复后的应用程序,从而在无需物理访问的情况下恢复设备。

那么,与默认的 STM32 CMake 项目相比,项目结构有什么变化呢?

[LOADING...]

提示: 在 STM32CubeMX 中,外设可以分配给安全和非安全区域,如上图所示。

STM32CubeMX 生成的代码实际上是两个独立的子项目,它们封装在一个可以构建两者的超级项目 中。根 CMake 项目仅提供构建这两个子项目所需的基础构建机制。它还包含两个子项目引用的共享代码,例如硬件驱动程序及其之上的 HAL。用 CMake 的术语来说,这是通过 ExternalProject_Add 指令完成的。以下是这个超级项目结构在 CLion 中的样子:

[LOADING...]

但是,有一个重要的注意事项:子项目在项目实际构建之前不会被配置。这意味着,为了让 CMake 报告 CLion 用于代码洞察的任何信息,必须先构建超级项目。然后,CLion 将自动收集必要的信息。

在 CLion 中配置项目

首先,从 GitHub 克隆我们的示例存储库,并将 .ioc 文件作为项目打开。打开的默认编辑器应该会向您显示项目 MCU 的名称,以及一个使用 STM32CubeMX 打开它以进行重新配置的选项。

如果您无法访问我们使用的硬件,您也可以使用 STM32CubeMX 生成自己的项目。选择生成启用了 TrustZone 的项目的选项,配置您需要的外设,并为 CMake 生成(无论您选择哪种编译器都无关紧要;我们同时支持 GCC 和 ST-ARM-CLANG)。

正如我上面提到的,我们现在需要做的就是构建项目,我们将在子项目中获得代码洞察。

如果您是 CLion 的新手,请参阅我们更详尽的 文档,以了解如何打开 STM32 项目或创建新项目、配置和构建它。

提示: CLion 尊重 CMake 目标的 FOLDER 属性,但这会在项目运行配置中创建不必要的结构。您可以转到高级设置,并通过禁用 Group CMake run configurations by FOLDER property(按 FOLDER 属性对 CMake 运行配置进行分组)来关闭此功能。

[LOADING...]

设置调试

遗憾的是,对应于添加到超级项目中的安全和非安全子项目的 CMake 目标不包含有关编译文件的信息。您需要在运行配置中手动输入这些内容。编辑两个运行配置,并选择相应的二进制文件作为可执行文件:

[LOADING...]

我们正在研究解决 CMake 外部项目这一限制的方法。(CPP-48380)。

[LOADING...]

提示: 非安全目标依赖于安全目标,因此当您构建非安全目标时,安全目标也会被构建。

请查阅您使用的 MCU 的手册,以了解如何在特定硬件上启用和禁用 TrustZone。按照 STM 入门教程,我们使用 STM32CubeProgrammer 在开发板上配置了以下选项字节:TZEN=1SECWM2_PSTRT=0x1SECWM2_PEND=0x0

[LOADING...]

如果您使用我们的示例项目或按照我们的说明将 .ioc 文件作为项目打开,那么您已经设置了调试服务器。如果您是从头开始,ST-LINK 调试服务器应该已在 Settings | Debugger 中预选并预配置。它旨在简化设置,旨在适用于大多数常见情况。

[LOADING...]

然而,今天我们要讨论的是一个稍微复杂一点的情况,所以我们需要一些更强大、更通用的东西。如果您跟随我们的示例,您将在项目中找到已设置好的 Generic(通用)调试服务器——我们将使用该服务器。请注意,您可能需要在 Settings | Advanced Settings | Debugger 中启用 Debug Servers 才能看到它。

如果您是从头开始,请将 ST-LINK 调试服务器转换为 Generic(使用 Name 字段旁边的按钮)。这是一个功能更强大的选项,允许完全自定义。我们需要调整一些设置,以便能够刷写两个镜像,而不是像默认情况下那样只刷写一个。我们正在研究自动化此过程 (CPP-48379)。

[LOADING...]

在通用调试服务器的 Debugger 选项卡中,转到 Connection 部分,选择 Script | Custom(脚本 | 自定义)选项,并添加以下内容:

# Connect to GDB Server
$GDBTargetCommand$

# Flash NonSecure binary
exec-file NonSecure/build/stm32l5-trustzone_NS.elf
load

# Flash Secure binary and load its symbols
file Secure/build/stm32l5-trustzone_S.elf
load

# Load symbols from NonSecure binary
add-symbol-file NonSecure/build/stm32l5-trustzone_NS.elf

# Reset the MCU
monitor reset

您可以在我们的示例中找到带有日志回显的此脚本的扩展版本。该脚本连接到您的设备,上传非安全和安全固件,加载必要的调试信息,并重置设备。

提示: $GDBTargetCommand$ 表达式是一个 IDE 宏,它扩展为连接脚本,就像在自动模式下生成一样。当您选择自动模式时会显示预览——例如,target remote tcp:localhost:12345

既然我们现在手动执行所有这些步骤,让我们禁用自动添加的步骤,以免我们做两次相同的工作。在 Device Settings 选项卡中,将 Upload executable to device(将可执行文件上传到设备)设置为 Never(从不),并取消选择 Reset 的两个选项。

[LOADING...]

现在,如果您按照我们的硬件设置进行了操作,您应该能够设置几个断点并开始调试了!

[LOADING...]

但是,请小心,不要操之过急。硬件断点的数量在设计上是有限的(在我们的 STM32L5 上为 6 个)。这意味着您可能会比预期更快地用完断点,尤其是在处理共享代码时。在共享代码中设置断点会消耗两倍的资源——代码被编译到两个镜像中,被刷写两次,并且每个代码副本都需要一个硬件断点。

禁用 TrustZone

遵循本文后,您可能需要在 MCU 上禁用 TrustZone 模式。在这里,我们简要总结上述手册中的说明。有关如何处理您的情况,请参阅您设备的手册。

要禁用 TrustZone:

  1. 将读出保护级别提高到 1(通过将 RDP 设置为 DC、0.5 或 2),这会禁用安全代码的调试。请注意,将保护级别设置为 2 也会禁用非安全代码的调试,这就是我们之前没有这样做的原因。
  2. 将 BOOT0 引脚提升到 VDD 电压。
  3. 对 IPP 跳线进行重新插拔(断开并重新连接)。在此阶段,两个 LED 应该亮起。之后,您应该能够在 Hot-plug(热插拔)模式下通过 STM32CubeProgrammer 连接。
  4. 同时将读出级别设置为 0(RDP 设置为 AA)并禁用 TZEN。

如有必要,您现在可以恢复第二个 Flash 扇区的内存安全级别。

接下来做什么

有任何问题,或者有什么没有按描述工作?请给我们留言,或在 2026 年嵌入式世界大会参观我们,展位号 4 号馆 146 号展位。我们期待您的反馈!

我们计划为使用双核 MCU 以及具有 bootflash 或 bootrom 内存的 MCU 编写类似的演练。这些情况下的项目结构与外部 CMake 项目相似,但调试体验有所不同。

如前所述,我们正在积极努力改进对 STM32 项目的支持。非常欢迎任何关于适合您工作流程的想法,请在 YouTrack 中提交问题。

* Arm 和 TrustZone 是 Arm Limited(或其子公司或关联公司)在美国和/或其他地区的注册商标。