• 正文
  • 相关推荐
申请入驻 产业图谱

STM32 TrustZone工程的中断全放在Secure侧响应的示例

07/27 11:25
90
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

1.背景

当前工程基于STM32H563 TrustZone,分为Secure工程和Non-Secure共两个工程。

资源分配:Secure资源:TIM1、PD1、PF4。Non-Secure资源:TIM3、UART3、GPIO[PG0、PG4]。

功能目标:如何在不改变预定的各资源安全属性的前提下,将上述全部中断统一改在Secure侧响应。

调试工具及IDE环境:STM32CubeMxSTM32CubeIDE for vscode 插件 VSCODE 串口助手

2.实现原理

将全部中断切到Secure响应,不只是把IRQHandler()写到Secure工程。通常还要同时满足以下三个条件。

2.1 中断响应定位切到Secure侧

需要将相关IRQ的target state设为Secure,可在secure侧使用如下函数完成:NVIC_ClearTargetState(EXTI0_IRQn);// target EXTI0(PG0) to SecureNVIC_ClearTargetState(TIM3_IRQn);// target TIM3 to SecureNVIC_ClearTargetState(TIM1_UP_IRQn);// target TIM1 to Secure【它本就在secure侧】NVIC_ClearTargetState(EXTI1_IRQn);// target EXTI1(PD1) to Secure【它本就在secure侧】这样做就是将这些中断的硬件异常入口目标侧配置为Secure。

2.2 相关IRQ必须在Secure侧使能

原本某些IRQ的NVIC配置是在Non-Secure工程里完成的,那么切换到Secure响应后,Secure侧还必须重新使能这些中断响应。

本例程中,TIM3_IRQn和EXTI0_IRQn原本属于Non-Secure路径,因此在secure侧还须补充:HAL_NVIC_EnableIRQ(EXTI0_IRQn);HAL_NVIC_EnableIRQ(TIM3_IRQn);

2.3 若Secure侧基于HAL库操作Non-Secure外设,须建立最小HAL软件上下文。

对于TIM3,虽然TIM3位于Non-Secure,但中断已改到Secure处理。若在Secure侧继续调用HAL_TIM_IRQHandler(&htim3),则至少保证:htim3.Instance = TIM3;否则基于HAL库构建的中断入口调用HAL_TIM_IRQHandler()就会访问:htim->Instance->DIERhtim->Instance->SR此时,会因为Instance无效而触发异常。对于UART3,虽然UART3位于Non-Secure,但Secure侧的中断回调仍需要通过它输出字符串。

Secure侧如果要调用HAL_UART_Transmit(&huart3, ...),除了要绑定实例外:huart3.Instance = USART3;还要补齐最小HAL状态机上下文:huart3.gState= HAL_UART_STATE_READY;huart3.RxState = HAL_UART_STATE_READY;huart3.Lock= HAL_UNLOCKED;也就是说,Secure侧访问Non-Secure UART3,虽无须重新初始化硬件,但要在Secure侧建立一个最小可用的HAL句柄上下文。目的是为了符合HAL库相关状态机管理,否则无法正常调用HAL库API

3.最终的关键配置

本次调试确认有效的关键参考代码如下。

3.1 在secure执行中断响应目标切换

NVIC_ClearTargetState(EXTI0_IRQn);// target EXTI0(PG0) to SecureNVIC_ClearTargetState(TIM3_IRQn);// target TIM3 to Secure

3.2 在Secure侧使能原本由NS管理的IRQ

HAL_NVIC_EnableIRQ(EXTI0_IRQn);HAL_NVIC_EnableIRQ(TIM3_IRQn);

3.3 在Secure侧补写最小TIM3 HAL句柄绑定

htim3.Instance = TIM3;

3.4 在Secure侧补写最小UART3 HAL句柄上下文【如不用HAL库另当别论】

huart3.Instance = USART3;huart3.gState= HAL_UART_STATE_READY;huart3.RxState = HAL_UART_STATE_READY;huart3.Lock= HAL_UNLOCKED;

4.代码建议

4.1 仅需在Secure侧的it.c文件里保留或增加必要的IRQHandler

/* EXTI Line0 interrupt  */ void EXTI0_IRQHandler(void) {   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); }/*  EXTI1 (PD1) handled in Secure domain  */void EXTI1_IRQHandler(void){  /* USER CODE BEGIN EXTI1_IRQn 0 */  /* USER CODE END EXTI1_IRQn 0 */  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);  /* USER CODE BEGIN EXTI1_IRQn 1 */  /* USER CODE END EXTI1_IRQn 1 */}
void TIM1_UP_IRQHandler(void){  /* USER CODE BEGIN TIM1_UP_IRQn 0 */  /* USER CODE END TIM1_UP_IRQn 0 */  HAL_TIM_IRQHandler(&htim1);  /* USER CODE BEGIN TIM1_UP_IRQn 1 */  /* USER CODE END TIM1_UP_IRQn 1 */}/*  TIM3 global interrupt  */void TIM3_IRQHandler(void){  HAL_TIM_IRQHandler(&htim3);}

4.2 Secure侧统一处理全部中断回调代码


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){  if (htim->Instance == TIM1)  {    /* toggle PF4 output */    HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_4);
    uart_sync_lock();    HAL_UART_Transmit(&huart3, (uint8_t *)"TIM1 event from Securernrn", sizeof("TIM1 event from Securernrn") - 1, 100);    uart_sync_unlock();  }    else if (htim->Instance == TIM3)  {    /* toggle PG4 output */    HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_4);     uart_sync_lock();    HAL_UART_Transmit(&huart3, (uint8_t *)"TIM3 event from NSrnrn", sizeof("TIM3 event from NSrnrn") - 1, 100);    uart_sync_unlock();  }}
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin){  if (GPIO_Pin == GPIO_PIN_1)  {      uart_sync_lock();    HAL_UART_Transmit(&huart3, (uint8_t *)"EXTI from PD1 Securernrn", sizeof("EXTI from PD1 Securernrn") - 1, 100);    uart_sync_unlock();  }  else if (GPIO_Pin == GPIO_PIN_0)  {       uart_sync_lock();    HAL_UART_Transmit(&huart3, (uint8_t *)"EXTI from PG0_NSrnrn", sizeof("EXTI from PG0_NSrnrn") - 1, 100);    uart_sync_unlock();  }}

5、小结

经测试证明,在STM32H563 TrustZone工程中,将全部中断统一放在Secure侧响应是可以做到的【当然,原理上也是支持的】。对于从Non-Secure路径迁移到Secure响应的中断,需要注意中断响应的target、IRQ NVIC enable、以及最小HAL软件上下文三方面的调整及处理。

当然,如果反过来,将全部中断统一放在Non Secure侧响应也是可以的,或者说,全部中断兵分两侧也可以【注意,是分两侧放而不是同时放两侧】,最终视具体应用需求而定。分享上面实现过程,仅供参考。下次再聊~!

相关推荐