4. 配置TZPC外设控制器

任务目标

在STM32H5系列(或集成TZPC的STM32 TrustZone器件)上,通过配置TZPC外设控制器,将指定外设(如USART、GPIO端口)标记为安全属性,使非安全世界(Non-secure)无法访问这些外设。本案例聚焦TZPC的寄存器级配置,不涉及操作系统或完整安全启动流程。

必要环境与依赖

  • 硬件:STM32H563 Nucleo板(或任何带TZPC的STM32H5系列)
  • 软件:STM32CubeIDE 1.15+,或任何支持ARM GCC的IDE
  • 依赖:CMSIS设备头文件(stm32h563xx.h),由STM32Cube包提供
  • 调试:板载ST-Link,用于观察寄存器值

核心实现

TZPC外设控制器通过一组32位寄存器控制外设的安全/非安全属性。每个寄存器位对应一个外设实例。关键寄存器为TZPC_RPR(外设安全配置寄存器),位为1表示安全,0表示非安全。复位后所有外设默认为安全属性。

以下代码将USART1和GPIOA配置为安全外设,并验证配置结果:

#include "stm32h563xx.h"

void TZPC_Init(void) {
    // 1. 使能TZPC时钟(通过RCC)
    RCC->AHBENR |= RCC_AHBENR_TZPCEN;

    // 2. 解锁TZPC配置寄存器(写0xC3A5C35A到TZPC_CR)
    TZPC->CR = 0xC3A5C35A;

    // 3. 配置外设安全属性
    //    RPR寄存器位映射(以STM32H5参考手册为准):
    //    bit0: USART1, bit1: USART2, ..., bit16: GPIOA, bit17: GPIOB
    //    将USART1(bit0)和GPIOA(bit16)设为安全(写1)
    TZPC->RPR = (1U << 0) | (1U << 16);

    // 4. 锁定配置(写0x0F0F0F0F到TZPC_CR)
    TZPC->CR = 0x0F0F0F0F;
}

// 验证函数:读取配置并返回安全状态
uint32_t TZPC_CheckSecure(void) {
    // 读取RPR寄存器,检查USART1和GPIOA位
    uint32_t rpr_val = TZPC->RPR;
    uint32_t usart1_secure = (rpr_val >> 0) & 1U;
    uint32_t gpioa_secure = (rpr_val >> 16) & 1U;
    return (usart1_secure << 0) | (gpioa_secure << 1);
}

int main(void) {
    // 初始化TZPC
    TZPC_Init();

    // 验证配置
    uint32_t status = TZPC_CheckSecure();
    // status bit0=1表示USART1安全,bit1=1表示GPIOA安全

    while (1) {
        // 空循环,可在调试器中观察status值
    }
}

运行与验证

  1. 在STM32CubeIDE中创建新项目,选择STM32H563ZI芯片。
  2. 将上述代码复制到main.c中,替换默认生成的代码。
  3. 编译并下载到开发板。
  4. 在调试模式下,将status变量添加到Watch窗口。
  5. 单步执行到while(1)处,观察status值应为0x03(二进制11),表示USART1和GPIOA均被配置为安全属性。

通过条件:status == 0x03,且TZPC->RPR寄存器读值为0x00010001(bit0和bit16为1)。

常见问题

  • RCC使能失败:确认RCC_AHBENR_TZPCEN宏在当前设备头文件中存在;若编译报错,检查是否包含正确的设备头文件。
  • 寄存器位映射错误:不同型号的TZPC位映射可能不同,务必查阅对应参考手册的TZPC章节确认外设对应的位号。
  • 非安全访问验证:若需验证非安全世界无法访问,可在非安全代码中尝试访问USART1寄存器,应触发总线错误(HardFault)。