[信息] STM32H5在使能TrustZone下实现外部中断的共享

[复制链接]
150|0
STM新闻官 发表于 2025-11-2 09:55 | 显示全部楼层 |阅读模式
1. 前言
在TrustZone架构中,中断是可以分配到S或者NS侧的,所以在很多的场景中,为了充分利用MCU的资源,中断的重映射就成了很常见的需求。 本文将展示如何在使能TrustZone的STM32H5上,实现外部中断的共享,即实现将外部中断动态分配给S和NS侧。

2. 创建工程
基于STM32H563ZI-NUCLEO实验板,STM32H5通过串口接收上位机的指令,来决定外部中断按键是响应S侧的中断服务函数,还是NS侧的中断服务函数。 通过STM32CubeMX创建基于STM32H5的激活了TrustZone的基础工程,可以从选择芯片开始创建工程。

584456906b86828ea5.png 3. 在S侧的secure_nsc.c 文件中,添加如下代码,实现中断的重映射:
547906906b874edf75.png
945166906b88015dc8.png
86346906b88a78388.png
753326906b899c22a7.png
931516906b8a98fdc7.png
在STM32CubeMX中完成上述配置,就可以生成代码了,然后编译,正常的话,工程是可以编译通过的。因为本文不考虑ICACHE,所以在下图中选择“Yes”,即生成代码。
728436906b8bc5c9e6.png
2.1. NS侧应用示例 1. 在NS侧的main.c文件中,添加以下宏定义和变量的申明:
  1. /* USER CODE BEGIN PV */  
  2. #define PRINTF_UART_INSTANCE huart3
  3. uint8_t rxBuffer=0;
  4. /* USER CODE END PV */
2. 实现串口重定向,外部中断的回调函数(翻转NS侧的LED2和LED3)。
  1. /* USER CODE BEGIN PV */  
  2. #ifdef __GNUC__
  3. int _write(int file, char *ptr, int len)
  4. {
  5. /* Wait for the ready status of the transfer */
  6. while(RESET == __HAL_UART_GET_FLAG(&PRINTF_UART_INSTANCE, UART_FLAG_TXE));
  7. /* Start the transmission process */
  8. if (HAL_UART_Transmit(&PRINTF_UART_INSTANCE, (uint8_t *)ptr, len,
  9. HAL_MAX_DELAY) != HAL_OK)
  10. {
  11.   Error_Handler();
  12. }

  13. /* Wait for the end of the transfer */
  14. while(RESET == __HAL_UART_GET_FLAG(&PRINTF_UART_INSTANCE, UART_FLAG_TC));

  15. return len;
  16. }
  17. #endif /* __GNUC__ */
  18. void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
  19. {
  20. printf("Button pressed in NS!\r\n");
  21. HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
  22. HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
  23. }/* USER CODE END PV */
3. 在NS侧的主函数中,添加如下代码实现信息的输出,以及接收上位机的命令:
  1.   /* USER CODE BEGIN 2 */
  2.   
  3. printf("======================================================\r\n");
  4.   printf("= STM32H563 Re-TargetISR\r\n");
  5.   printf("= Build time: %s %s\r\n", __DATE__, __TIME__);
  6.   
  7. printf("======================================================\r\n");
  8.   /* USER CODE END 2 */
  9.   /* Infinite loop */
  10.   /* USER CODE BEGIN WHILE */
  11.   while (1)
  12.   {
  13.    if(HAL_UART_Receive(&huart3, &rxBuffer, 1, 100) == HAL_OK)
  14.    {
  15.     printf("= UartRx: 0x%x\r\n", rxBuffer);
  16.     SECURE_RetargetISR(rxBuffer);
  17.    }
  18. /* USER CODE END WHILE */
  19.   /* USER CODE BEGIN 3 */
  20.   }
  21.   /* USER CODE END 3 */
  1. /* USER CODE BEGIN 1 */
  2. /**
  3.   * [url=/u/brief]@brief[/url] This function handles EXTI Line13 interrupt.
  4.   */
  5. void EXTI13_IRQHandler(void)
  6. {
  7.   /* USER CODE BEGIN EXTI13_IRQn 0 */

  8.   /* USER CODE END EXTI13_IRQn 0 */
  9.   HAL_GPIO_EXTI_IRQHandler(B1_USER_Pin);
  10.   /* USER CODE BEGIN EXTI13_IRQn 1 */

  11.   /* USER CODE END EXTI13_IRQn 1 */
  12. }

  13. /* USER CODE END 1 */
  1. /* USER CODE BEGIN 4 */
  2. void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
  3. {
  4. HAL_GPIO_TogglePin(LD1_GPIO_Port, LD1_Pin);
  5. }
  6. /* USER CODE END 4 */
3. 在S侧的secure_nsc.c 文件中,添加如下代码,实现中断的重映射:


  1. CMSE_NS_ENTRY void SECURE_RetargetISR(uint8_t flag)
  2. {
  3.   if(flag == 0x31)
  4.   {
  5.     NVIC_DisableIRQ(EXTI13_IRQn);
  6.     HAL_EXTI_ConfigLineAttributes(EXTI_LINE_13, EXTI_LINE_NSEC);
  7.     NVIC_SetTargetState(EXTI13_IRQn);
  8.     NVIC_EnableIRQ(EXTI13_IRQn);
  9.   }
  10.   else if(flag == 0x30)
  11.   {
  12.     NVIC_DisableIRQ(EXTI13_IRQn);
  13.     HAL_EXTI_ConfigLineAttributes(EXTI_LINE_13, EXTI_LINE_SEC);
  14.     NVIC_ClearTargetState(EXTI13_IRQn);
  15. NVIC_EnableIRQ(EXTI13_IRQn);
  16. }
  17. }
4. 在 secure_nsc.h 中申明该函数:
  1. void SECURE_RegisterCallback(SECURE_CallbackIDTypeDef CallbackId, void *func);
  2. void SECURE_RetargetISR(uint8_t flag);
2.3. 其他注意事项 1. 不可以在外设中断里面重映射当前的中断,这样会引发Fault。
2. 编译顺序:TrustZone架构中,要求先编译S工程,然后再编译NS工程;但下载不区分先后顺序。
2.4. 选项字节的配置 对于TrustZone架构中,芯片的选项字节同样也要有对应的配置。
1. 使能TrustZone
123836906b98aa8139.png
2. 配置Flash Watermark
312836906b99bf293e.png
在使用STM32CubeProgrammer完成上述配置之后,我们便可以将S和NS的程序分别下载到芯片中,然后按下开发板的复位按钮。

3. 验证 打开串口终端连接上串口,按下复位按钮,我们可以看到如下信息;当我们直接按下开发板上的用户按键时,可以看到LED2和LED3同时翻转,这是NS侧的外部中断实现的功能。当通过串口工具发送0x30(如果使用其他不支持16进制发送的串口终端,可直接输入0)给MCU之后,再次按下按钮时,能看到仅有LED1在翻转,说明外部中断被重映射到S侧了,实验完成。   
958596906b9c459882.png
4. 小结 本文实验附有完整的实验工程供大家直接使用,希望对大家有所帮助。

文档中所用到的工具及版本
STM32CubeMX V6.14.1 STM32CubeIDE V1.17.0  STM32CubeProgrammer V2.19.0 XCOM V2.0

LAT中的附件  LAT1591 STM32H5 在使能TrustZone下实现外部中断的共享_V0.2.zip
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:意法半导体(中国)投资有限公司
简介:您的嵌入式应用将得益于意法半导体领先的产品架构、技术、多源产地和全方位支持。意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器。

1428

主题

1758

帖子

25

粉丝
快速回复 在线客服 返回列表 返回顶部