Skip to main content
Associate II
July 7, 2026
Question

Setup HAL UART Interrupts in a Trustzone environment without CubeMX

  • July 7, 2026
  • 3 replies
  • 38 views

Hi ST,

I’ve run into a whole lot of issues adding interrupt-based UART to your OEMiRoT w/ Trustzone example on a NUCLEO-U385RG-Q.

As you may know this example is not compatible with CubeMX, and it’s not clear which steps are needed to manually incorporate UART4 so that it activates an interrupt on receipt of input when running in the Non-Secure region of code. The idea is to only access the Secure region when needing to utilise certain sensitive variables, called from within a Non-Secure function.

Let’s take this opportunity to establish a step-by-step guide for someone who isn’t (yet) an embedded professional, please excuse my ignorance if this already exists, I’d be just as happy to be directed there. My settings so far are:

1. Secure/Inc/partition_stm32u385xx.h: Initialise UART4_IRQn as Non-Secure
#define NVIC_INIT_ITNS2    1
#define NVIC_INIT_ITNS2_VAL      0x00000001

2. Secure/Src/main.c: Define UART4 pins (CN7 1 & 2, or PC10 & 11) as NonSecure
HAL_GPIO_ConfigPinAttributes(GPIOC, GPIO_PIN_10|GPIO_PIN_11, GPIO_PIN_NSEC);

3. NonSecure/Src/stm32u3xx_it.c: Define interrupt handler (+ function definition in the related header file)

void UART4_IRQHandler(void) {
  HAL_UART_IRQHandler(&huart4);
}

4. NonSecure/Src/main.c: Add Interrupt enable and priority inside MX_UART4_Init

  HAL_NVIC_SetPriority(UART4_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(UART4_IRQn);

5. NonSecure/Src/main.c: Add UART RX Interrupt callback

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ 
HAL_UART_Receive_IT(&huart4, &uart_rx_byte, 1);
}

Is there anything here I don’t need to do? And the more obvious question - what am I missing?

For future reference - how is a ‘successful’ user currently accessing this kind of information without needing your forum? I have 4 seperate user manuals consisting of the nucleo user manual (MB1841), the STM32U3 user manual (RM0487), the programmers manual (PM0264) and the TrustZone application note (AN5347) and neither of them contain a clear guide to implementing this basic(?) functionality.

Thanks for your help!


 

3 replies

Jocelyn RICARD
ST Employee
July 8, 2026

Hello ​@AdsBot ,

I agree there is no specific documentation helping with stepping into TrustZone step by step.

AN5347 provides a good overview but does not make the link to the actual implementation using HAL for instance.

One possible way to know what is needed to add in context of TrustZone is to create an empty TrustZone project with STM32CubeMX.

From first code generation you create a first git commit that is the baseline.

Then add your peripheral in non secure, here the UART for instance, and launch code generation again.

The git diff will give you all the changes required to make it work.

 

Regarding the integration of a CubeMX generated project as an application run by STM32U3 OEMiROT there is no specific resource available.

I will ask internally to create a wiki page for that.

Best regards

Jocelyn

AdsBotAuthor
Associate II
July 10, 2026

Hi ​@Jocelyn RICARD,

Thanks for getting back to me, appreciate the support.

Excuse the code dump but I thought I’d provide the results of my git diff to help narrow down the issue, as my OEMiRoT project is still not responding to UART.

I didn’t add any of the code in the first five files (all the .cproject, .project etc) because I assume just the source code is relevant. All the code I have included is what I added to my OEMiRoT project. I also added all the ‘untracked files’ into my NonSecure\Inc folder as that’s the domain using the UART.

Did you have any other ideas I could try, or spot anything here that is missing?


Changes not staged for commit:
modified: .mxproject
modified: BasicProject.ioc
modified: NonSecure/.cproject
modified: NonSecure/.project
modified: Secure/.cproject

modified: NonSecure/Core/Inc/stm32u3xx_hal_conf.h
+#define HAL_UART_MODULE_ENABLED

modified: NonSecure/Core/Inc/stm32u3xx_it.h
+void UART4_IRQHandler(void);

modified: NonSecure/Core/Src/main.c

+UART_HandleTypeDef huart4;
+static void MX_UART4_Init(void);
+ MX_UART4_Init();

+static void MX_UART4_Init(void)
+{
+ huart4.Instance = UART4;
+ huart4.Init.BaudRate = 115200;
+ huart4.Init.WordLength = UART_WORDLENGTH_8B;
+ huart4.Init.StopBits = UART_STOPBITS_1;
+ huart4.Init.Parity = UART_PARITY_NONE;
+ huart4.Init.Mode = UART_MODE_TX_RX;
+ huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+ huart4.Init.OverSampling = UART_OVERSAMPLING_16;
+ huart4.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
+ huart4.Init.ClockPrescaler = UART_PRESCALER_DIV1;
+ huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
+}
+ __HAL_RCC_GPIOC_CLK_ENABLE();

modified: NonSecure/Core/Src/stm32u3xx_hal_msp.c
+void HAL_UART_MspInit(UART_HandleTypeDef* huart)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+ if(huart->Instance==UART4)
+ {
+ /* USER CODE BEGIN UART4_MspInit 0 */
+
+ /* USER CODE END UART4_MspInit 0 */
+
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_UART4;
+ PeriphClkInit.Uart4ClockSelection = RCC_UART4CLKSOURCE_PCLK1;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /* Peripheral clock enable */
+ __HAL_RCC_UART4_CLK_ENABLE();
+
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ /**UART4 GPIO Configuration
+ PC10 ------> UART4_TX
+ PC11 ------> UART4_RX
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ /* UART4 interrupt Init */
+ HAL_NVIC_SetPriority(UART4_IRQn, 0, 0);
+ HAL_NVIC_EnableIRQ(UART4_IRQn);
+ /* USER CODE BEGIN UART4_MspInit 1 */
+
+ /* USER CODE END UART4_MspInit 1 */
+
+ }
+
+}

+void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
+{
+ if(huart->Instance==UART4)
+ {
+ /* USER CODE BEGIN UART4_MspDeInit 0 */
+
+ /* USER CODE END UART4_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_UART4_CLK_DISABLE();
+
+ /**UART4 GPIO Configuration
+ PC10 ------> UART4_TX
+ PC11 ------> UART4_RX
+ */
+ HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10|GPIO_PIN_11);
+
+ /* UART4 interrupt DeInit */
+ HAL_NVIC_DisableIRQ(UART4_IRQn);
+ }
+}

modified: NonSecure/Core/Src/stm32u3xx_it.c
+extern UART_HandleTypeDef huart4;
+void UART4_IRQHandler(void)
+ HAL_UART_IRQHandler(&huart4);

modified: Secure/Core/Inc/partition_stm32u385xx.h
+// <o.0> UART4_IRQn <1=> Non-Secure state
+#define NVIC_INIT_ITNS2_VAL 0x00000001

modified: Secure/Core/Src/main.c
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ HAL_GPIO_ConfigPinAttributes(GPIOC, GPIO_PIN_10|GPIO_PIN_11, GPIO_PIN_NSEC);

Untracked files:
(use "git add <file>..." to include in what will be committed)
Drivers/STM32U3xx_HAL_Driver/Inc/stm32u3xx_hal_uart.h
Drivers/STM32U3xx_HAL_Driver/Inc/stm32u3xx_hal_uart_ex.h
Drivers/STM32U3xx_HAL_Driver/Inc/stm32u3xx_ll_lpuart.h
Drivers/STM32U3xx_HAL_Driver/Inc/stm32u3xx_ll_usart.h
Drivers/STM32U3xx_HAL_Driver/Src/stm32u3xx_hal_uart.c
Drivers/STM32U3xx_HAL_Driver/Src/stm32u3xx_hal_uart_ex.c

 

AdsBotAuthor
Associate II
July 12, 2026

*added the untracked .h files to NonSecure\Inc folder, and the .c files to the NonSecure\Src file