Skip to main content
Explorer II
November 22, 2023
Solved

NETXDUO not working with enabled TrustZone

  • November 22, 2023
  • 7 replies
  • 6240 views

Hi everyone,

i'm currently facing some issues while using NetXDuo (in the NonSecure World) with TrustZone.

My current goal: Use Network stuff, i.e. be able to ping the board from my PC with NetXDuo running in the NonSecure World with activated TrustZone.

 

With an empty project, i do the following steps and assign the ETH to the NS world. Apart from that, the project is empty.
The steps are more or less taken from this example.

- ETH: `RMII` mode. Set RxBuffLen to `1536`
- ICACHE: (optional to disable the IDE warnings) `2-ways set associative cache` mode
- ThreadX: `Core`
- NetXDuo: NX Core, DHCP Client, Network Interfaces > Ethernet Interfacea and LAN8472. In the configuration:
 - Platform Settings > chose lan8742 for both options
 - Enable Interface Capability true
 - Memory Pool Size 30 * 1024
 - Generate Init Code true
 - IP Instance Thread Size 2 * 1024
 - Pool Size in number of Packets 10
 - Application Thread Stack Size 2 * 1024
- NVIC: Enable Ethernet Global Interrupt to Preemption Prio 7
- SYS: Timebase Source TIM6
- RCC: Enable High Speed Clock > DIGBYPASS Clock Source
- Pinout: Set Pin PG12 to `ETH_TXD1`. (By doing this, PG14 should be cleared)

 

If i run the project like this, the wati until an IP Address is ready semaphore get in app_netxduo.c does not return to TX_SUCCESS, i.e. the board is not pingable. 

 

What kinda confuses me is that if i do the steps above in an Project without TrustZone, everything works.

 

Anyone got an idea what might be my issue? I also tried to compare the .ioc files by hand in an editor and did not spot anything what might be a problem.

 

I'd appreciate any help or hints :)

Best,

funkii

    This topic has been closed for replies.
    Best answer by funkii

    Hi,

    i finally managed to get it working! Thanks @STea for your help, I really appreciate it.

    Steps to get it working:

    Start Board Project with Trustzone enabled
    Firmware Version v1.1.1
    
    Clear pinout
    
    ETH
     Mode RMII
     RxBuffLen 1536
     Set Pin PG12 to ETH_TXD1 (By doing this, PG14 should be cleared)
    
    THREADX
     Core
    
    NETXDUO
     NX Core
     Addons > DHCP > Client
     Network Interfaces > Ethernet interface, Ethernet Phy Interface > LAN8742
     Platform Settings > both lan8742
    
     Enable Interface Capability true
     memory pool size 30 * 1024
     Genreate Init Code true
     IP Instance Thread Size 2 * 1024
     Pool Size in number of Packets 10
     Application Thread Stack Size 2 * 1024
    
    NVIC_NS
     Ethernet global Interupt > Enable, Preemption Priority 7
    
    SYS
     Timebase Source TIM6 (Assign TIM6 to NS before)
    
    RCC
     High speed Clock DIGBYPASS Clock source
    
    GTZC_S
     Block-Based Memory Controller > MPCBB3 (SRAM3) > Memory Privilege Attributes Settings > Configure Memory > from full Not privileged
     (Setting the whole SRAM3 to not priviliged might not be the best idea from an security standpoint if you do other stuff on the board)
    
    Manual change in Secure/Core/Inc/partition_stm32h573xx.h:
    Set the 10th bit in NVIC_INIT_ITNS3_VAL (in my case line 554), so the line should look like this:
    `#define NVIC_INIT_ITNS3_VAL 0x00000400`
    IMPORTANT: After each code-generation check if the bit is still set or overwritten by the code-generation. 
    
    Build and run like normal trustzone project e.g. described here https://github.com/STMicroelectronics/STM32CubeH5/tree/main/Projects/STM32H573I-DK/Examples/GTZC/GTZC_MPCWM_IllegalAccess_TrustZone
    
    You should now be able to ping the board!

     

    One last question: 

    I need to manually change the Pinlayout of ETH to get it working, i.e. assign ETH_TXD1 to PG12.

    Additionally my issue with the Interrupt where i manually need to set a bit in the files.

    Are these known issues or can I report them somewhere?

    Same goes for the MPCBB config, i understand that you might expect developers to do this by themselfs, but a small note when assigning ETH to NonSecure would be really nice as debugging this is kinda pain.

     

    Again, thanks for your help.

    Best,

    funkii

    7 replies

    ST Employee
    November 23, 2023

    Hello @funkii ,

    1. what is your entry point for the non secure project ?
    2. what is done in the secure project ?
    3. are you sure that when you are pinging the board you are in non secure state and running the dedicated code for NETX ? if it's the case are you sure that you are passing the  tx_application_define() function successfully .
    4. the semaphore blocking you is  put in the  ip_address_change_notify_callback() function . try to visualise if the app is executing this function 

    BR

     

    funkiiAuthor
    Explorer II
    November 23, 2023

    Hi,

    thank you for your reply!

    My starting point is an completely empty TrustZone project. Besides the steps in the original post i do not modify anything (except for the for(;;); loops in nx_app_thread_entry()).


    So for 1) I'm not really sure what you mean, so I uploaded my NonSecure main.c here. It only does the basic Init stuff and then calls ThreadX with "MX_ThreadX_Init()"

    For 2) I dont really do anything in the Secure Part besides the auto-generated init stuff. I also uploaded the secure main.c here 

    3) I'm not 100% sure if I'm in the nonsecure state, but I did not add any context switch to the secure state, so the board should definitely be in the nonsecure state. As this 'just works' with deactivated TrustZone i supposed that i do not need to modify anything else. What do you mean with "if it's the case are you sure that you are passing the  tx_application_define() function successfully"?, could you explain this?

    4) The callback function never gets executed (tested with the debugger). For debugging reasons I added an infinite loop in the error case (Without that loop, i cannot ping the board aswell). I also tried to incrase the timeout in tx_semaphore_get() without success. I marked the spot where the execution lands in my nx_app_thread_entry 

     

    So as stated earlier, I only let the IDE auto-generate the code after choosing the options in the starting point. 

    If this helps, I also uploaded my .ioc file  .

    I'd appreciate it if you could get into detail about what you mean in 3).

    Best,

    funkii

    ST Employee
    November 27, 2023

    Hello @funkii ,

    The documents that you added in your previous post can't be opened so i suggest you upload them directly into the thread in the community.

    Passing now to he the third point of my previous post if are able to debug and point to the tx_application_define() and see its execution that confirms that you are in a non secure state because this code is found in the non secure project.

    after giving it some thought i recommend you check the memory mapping to see if there is any secure region overlapping an non secure one and i also recommend verifying that the gpio pins of the Ethernet are assigned to the non secure project for sure as well as the other peripherals like the timer.

    check if you can the address of the semaphore blocking your project  if it is in a secure or non secure memory page.

    check if there is any security enabled on the flash like MPU for example .

    waiting for some details on your configuration and code to help you further.

    BR 

     

    funkiiAuthor
    Explorer II
    November 27, 2023

    Hi,

    sorry for the problem with the links, but when i click on them they take me to pastebin.

    I additionally uploaded the ioc file here. I cannot upload all files in this post because of character restriction... The main.c of secure and nonsecure world are only the autogenerated files anyways, so i think the ioc file should be enough.

    ioc file:

     

    Spoiler
    #MicroXplorer Configuration settings - do not modify
    CAD.formats=
    CAD.pinconfig=
    CAD.provider=
    CORTEX_M33_NS.userName=CORTEX_M33
    CortexM33NS.IPs=CORTEX_M33_NS\:I,FILEX\:I,GPDMA1,GPDMA2,GPIO\:I,GTZC_NS\:I,LEVELX\:I,LINKEDLIST,NETXDUO\:I,NVIC2\:I,PWR,RCC,RTC,SYS\:I,TAMP,THREADX\:I,USBX\:I,SECURE_MANAGER_API\:I,ETH\:I,TIM6\:I
    CortexM33NS.Pins=PH0-OSC_IN(PH0)
    CortexM33S.IPs=CORTEX_M33_S\:I,GPDMA1\:I,GPDMA2\:I,GPIO,GTZC_S\:I,LINKEDLIST\:I,NVIC1\:I,OTFDEC1\:I,PWR\:I,RCC\:I,RTC\:I,SYS_S\:I,TAMP\:I,ICACHE\:I,ADC1\:I,ADC2\:I,SAI1\:I,SAI2\:I,I2C4\:I,DEBUG\:I,FMC\:I,USB\:I,USART1\:I,SDMMC1\:I,TIM1\:I,OCTOSPI1\:I,SPI5\:I,UCPD1\:I,I2C1\:I,USART3\:I,SAU\:I,MEMORYMAP\:I
    ETH.IPParameters=MediaInterface,RxBuffLen
    ETH.MediaInterface=HAL_ETH_RMII_MODE
    ETH.RxBuffLen=1536
    File.Version=6
    GPIO.groupedBy=Group By Peripherals
    GTZC_S.ADC_Secure=GTZC_TZSC_PERIPH_SEC
    GTZC_S.FMC_Secure=GTZC_TZSC_PERIPH_SEC
    GTZC_S.I2C1_Secure=GTZC_TZSC_PERIPH_SEC
    GTZC_S.I2C4_Secure=GTZC_TZSC_PERIPH_SEC
    GTZC_S.IPParameters=MPCBB3_SecConfig_array,ADC_Secure,FMC_Secure,I2C1_Secure,I2C4_Secure,OCTOSPI1_Secure,SAI1_Secure,SAI2_Secure,SDMMC1_Secure,SPI5_Secure,TIM1_Secure,UCPD1_Secure,USART1_Secure,USART3_Secure,USB_Secure
    GTZC_S.MPCBB3_SecConfig_array=00000000\:00000000\:00000000\:00000000\:00000000\:00000000\:00000000\:00000000\:00000000\:00000000\:00000000\:00000000\:00000000\:00000000\:00000000\:00000000\:00000000\:00000000\:00000000\:00000000
    GTZC_S.OCTOSPI1_Secure=GTZC_TZSC_PERIPH_SEC
    GTZC_S.SAI1_Secure=GTZC_TZSC_PERIPH_SEC
    GTZC_S.SAI2_Secure=GTZC_TZSC_PERIPH_SEC
    GTZC_S.SDMMC1_Secure=GTZC_TZSC_PERIPH_SEC
    GTZC_S.SPI5_Secure=GTZC_TZSC_PERIPH_SEC
    GTZC_S.TIM1_Secure=GTZC_TZSC_PERIPH_SEC
    GTZC_S.UCPD1_Secure=GTZC_TZSC_PERIPH_SEC
    GTZC_S.USART1_Secure=GTZC_TZSC_PERIPH_SEC
    GTZC_S.USART3_Secure=GTZC_TZSC_PERIPH_SEC
    GTZC_S.USB_Secure=GTZC_TZSC_PERIPH_SEC
    KeepUserPlacement=false
    Mcu.CPN=STM32H573IIK3Q
    Mcu.Context0=CortexM33S
    Mcu.Context1=CortexM33NS
    Mcu.ContextNb=2
    Mcu.ContextProject=TrustZoneEnabled
    Mcu.Family=STM32H5
    Mcu.IP0=CORTEX_M33_NS
    Mcu.IP1=CORTEX_M33_S
    Mcu.IP10=SYS
    Mcu.IP11=SYS_S
    Mcu.IP12=THREADX
    Mcu.IP2=ETH
    Mcu.IP3=GTZC_S
    Mcu.IP4=ICACHE
    Mcu.IP5=NETXDUO
    Mcu.IP6=NVIC2
    Mcu.IP7=NVIC1
    Mcu.IP8=PWR
    Mcu.IP9=RCC
    Mcu.IPNb=13
    Mcu.Name=STM32H573IIKxQ
    Mcu.Package=UFBGA176
    Mcu.Pin0=PG12
    Mcu.Pin1=PG13
    Mcu.Pin10=VP_GTZC_S_VS_GTZC_Enable
    Mcu.Pin11=VP_ICACHE_VS_SECURE_ICACHE_REG
    Mcu.Pin12=VP_NETXDUO_VS_NXOoCore
    Mcu.Pin13=VP_NETXDUO_VS_AddonsOoDHCP
    Mcu.Pin14=VP_NETXDUO_VS_NetworkOoInterface
    Mcu.Pin15=VP_NETXDUO_VS_EthernetOoPhyOoInterface
    Mcu.Pin16=VP_PWR_VS_SECSignals
    Mcu.Pin17=VP_SYS_VS_tim6
    Mcu.Pin18=VP_SYS_S_VS_Systick
    Mcu.Pin19=VP_THREADX_VS_RTOSJjThreadXJjCoreJjDefault
    Mcu.Pin2=PG11
    Mcu.Pin3=PH0-OSC_IN(PH0)
    Mcu.Pin4=PC1
    Mcu.Pin5=PA1
    Mcu.Pin6=PA2
    Mcu.Pin7=PC4
    Mcu.Pin8=PC5
    Mcu.Pin9=PA7
    Mcu.PinsNb=20
    Mcu.ThirdPartyNb=0
    Mcu.UserConstants=
    Mcu.UserName=STM32H573IIKxQ
    MxCube.Version=6.9.2
    MxDb.Version=DB.6.0.92
    NETXDUO.ETH_ON=1
    NETXDUO.IPParameters=ETH_ON,LAN_8742,NX_ENABLE_INTERFACE_CAPABILITY,NX_APP_MEM_POOL_SIZE,NetXDuo_Generate_Init_Code,NX_APP_IP_INSTANCE_THREAD_SIZE,NX_APP_PACKET_POOL_SIZE,NX_APP_THREAD_STACK_SIZE
    NETXDUO.LAN_8742=1
    NETXDUO.NX_APP_IP_INSTANCE_THREAD_SIZE=2*1024
    NETXDUO.NX_APP_MEM_POOL_SIZE=30*1024
    NETXDUO.NX_APP_PACKET_POOL_SIZE=10
    NETXDUO.NX_APP_THREAD_STACK_SIZE=2*1024
    NETXDUO.NX_ENABLE_INTERFACE_CAPABILITY=true
    NETXDUO.NetXDuo_Generate_Init_Code=true
    NVIC1.BFHFNMINS=0
    NVIC1.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
    NVIC1.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
    NVIC1.ForceEnableDMAVector=true
    NVIC1.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
    NVIC1.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
    NVIC1.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
    NVIC1.PRIS=0
    NVIC1.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
    NVIC1.PriorityGroup=NVIC_PRIORITYGROUP_4
    NVIC1.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
    NVIC1.SecureFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
    NVIC1.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
    NVIC1.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
    NVIC2.BFHFNMINS=0
    NVIC2.ETH_IRQn=true\:7\:0\:true\:false\:true\:false\:true\:true\:true
    NVIC2.ForceEnableDMAVector=true
    NVIC2.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
    NVIC2.PRIS=0
    NVIC2.PendSV_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false
    NVIC2.PriorityGroup=NVIC_PRIORITYGROUP_4
    NVIC2.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false
    NVIC2.SavedPendsvIrqHandlerGenerated=true
    NVIC2.SavedSvcallIrqHandlerGenerated=true
    NVIC2.SavedSystickIrqHandlerGenerated=true
    NVIC2.SysTick_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:true\:false
    NVIC2.TIM6_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true
    NVIC2.TimeBase=TIM6_IRQn
    NVIC2.TimeBaseIP=TIM6
    NVIC2.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
    NetXDuo.BSP.number=1
    NetXDuo0.BSP.STBoard=false
    NetXDuo0.BSP.api=BSP_COMPONENT_DRIVER
    NetXDuo0.BSP.component=lan8742
    NetXDuo0.BSP.condition=
    NetXDuo0.BSP.instance=lan8742
    NetXDuo0.BSP.ip=
    NetXDuo0.BSP.mode=
    NetXDuo0.BSP.name=LAN_Component
    NetXDuo0.BSP.semaphore=SEMA_lan8742
    NetXDuo0.BSP.solution=lan8742
    PA1.GPIOParameters=PinAttribute
    PA1.Mode=RMII
    PA1.PinAttribute=CortexM33NS
    PA1.Signal=ETH_REF_CLK
    PA2.GPIOParameters=PinAttribute
    PA2.Mode=RMII
    PA2.PinAttribute=CortexM33NS
    PA2.Signal=ETH_MDIO
    PA7.GPIOParameters=PinAttribute
    PA7.Mode=RMII
    PA7.PinAttribute=CortexM33NS
    PA7.Signal=ETH_CRS_DV
    PC1.GPIOParameters=PinAttribute
    PC1.Mode=RMII
    PC1.PinAttribute=CortexM33NS
    PC1.Signal=ETH_MDC
    PC4.GPIOParameters=PinAttribute
    PC4.Mode=RMII
    PC4.PinAttribute=CortexM33NS
    PC4.Signal=ETH_RXD0
    PC5.GPIOParameters=PinAttribute
    PC5.Mode=RMII
    PC5.PinAttribute=CortexM33NS
    PC5.Signal=ETH_RXD1
    PG11.GPIOParameters=PinAttribute
    PG11.Mode=RMII
    PG11.PinAttribute=CortexM33NS
    PG11.Signal=ETH_TX_EN
    PG12.GPIOParameters=PinAttribute
    PG12.Locked=true
    PG12.Mode=RMII
    PG12.PinAttribute=CortexM33NS
    PG12.Signal=ETH_TXD1
    PG13.GPIOParameters=PinAttribute
    PG13.Mode=RMII
    PG13.PinAttribute=CortexM33NS
    PG13.Signal=ETH_TXD0
    PH0-OSC_IN(PH0).ContextOwner=CortexM33NS
    PH0-OSC_IN(PH0).GPIOParameters=PinAttribute
    PH0-OSC_IN(PH0).Mode=HSE-DIG-External-Clock-Source
    PH0-OSC_IN(PH0).PinAttribute=CortexM33NS
    PH0-OSC_IN(PH0).Signal=RCC_OSC_IN
    PinOutPanel.CurrentBGAView=Top
    PinOutPanel.RotationAngle=0
    ProjectManager.AskForMigrate=true
    ProjectManager.BackupPrevious=false
    ProjectManager.CompilerOptimize=6
    ProjectManager.ComputerToolchain=false
    ProjectManager.CoupleFile=false
    ProjectManager.CustomerFirmwarePackage=
    ProjectManager.DefaultFWLocation=true
    ProjectManager.DeletePrevious=true
    ProjectManager.DeviceId=STM32H573IIKxQ
    ProjectManager.FirmwarePackage=STM32Cube FW_H5 V1.1.1
    ProjectManager.FreePins=false
    ProjectManager.HalAssertFull=false
    ProjectManager.HeapSize=M33S-0x200,M33NS-0x200
    ProjectManager.KeepUserCode=true
    ProjectManager.LastFirmware=true
    ProjectManager.LibraryCopy=1
    ProjectManager.MainLocation=Core/Src
    ProjectManager.NoMain=false
    ProjectManager.PreviousToolchain=
    ProjectManager.ProjectBuild=false
    ProjectManager.ProjectFileName=wip.ioc
    ProjectManager.ProjectName=wip
    ProjectManager.ProjectStructure=M33S\:Secure Project\:true;M33NS\:Non Secure Project\:true;
    ProjectManager.RegisterCallBack=
    ProjectManager.StackSize=M33S-0x400,M33NS-0x400
    ProjectManager.TargetToolchain=STM32CubeIDE
    ProjectManager.ToolChainLocation=
    ProjectManager.UAScriptAfterPath=
    ProjectManager.UAScriptBeforePath=
    ProjectManager.UnderRoot=true
    ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false-CortexM33S,2-MX_GPIO_Init-GPIO-false-HAL-true-CortexM33S,3-MX_GTZC_S_Init-GTZC_S-false-HAL-true-CortexM33S,4-MX_ICACHE_Init-ICACHE-false-HAL-true-CortexM33S,1-SystemClock_Config-RCC-false-HAL-false-CortexM33NS,2-MX_GPIO_Init-GPIO-false-HAL-true-CortexM33NS,3-MX_ETH_Init-ETH-false-HAL-true-CortexM33NS,4-MX_NetXDuo_Init-NETXDUO-false-HAL-false-CortexM33NS,0-MX_CORTEX_M33_S_Init-CORTEX_M33_S-false-HAL-true-CortexM33S,0-MX_PWR_Init-PWR-false-HAL-true-CortexM33S,0-MX_CORTEX_M33_NS_Init-CORTEX_M33_NS-false-HAL-true-CortexM33NS,0-MX_PWR_Init-PWR-false-HAL-true-CortexM33NS
    RCC.ADCFreq_Value=250000000
    RCC.AHBFreq_Value=250000000
    RCC.APB1Freq_Value=250000000
    RCC.APB1TimFreq_Value=250000000
    RCC.APB2Freq_Value=250000000
    RCC.APB2TimFreq_Value=250000000
    RCC.APB3Freq_Value=250000000
    RCC.CECFreq_Value=32000
    RCC.CKPERFreq_Value=64000000
    RCC.CRSFreq_Value=48000000
    RCC.CSI_VALUE=4000000
    RCC.CortexFreq_Value=250000000
    RCC.DACFreq_Value=32768
    RCC.EPOD_VALUE=25000000
    RCC.ETHFreq_Value=250000000
    RCC.FCLKCortexFreq_Value=250000000
    RCC.FDCANFreq_Value=25000000
    RCC.FamilyName=M
    RCC.HCLKFreq_Value=250000000
    RCC.HSE_VALUE=25000000
    RCC.HSI48_VALUE=48000000
    RCC.HSIDiv=RCC_HSI_DIV1
    RCC.HSI_VALUE=64000000
    RCC.I2C1Freq_Value=250000000
    RCC.I2C2Freq_Value=250000000
    RCC.I2C3Freq_Value=250000000
    RCC.I2C4Freq_Value=250000000
    RCC.I3C1Freq_Value=250000000
    RCC.IPParameters=ADCFreq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,APB3Freq_Value,CECFreq_Value,CKPERFreq_Value,CRSFreq_Value,CSI_VALUE,CortexFreq_Value,DACFreq_Value,EPOD_VALUE,ETHFreq_Value,FCLKCortexFreq_Value,FDCANFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI48_VALUE,HSIDiv,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2C4Freq_Value,I3C1Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM3Freq_Value,LPTIM4Freq_Value,LPTIM5Freq_Value,LPTIM6Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSE_VALUE,LSIRC_VALUE,MCO1PinFreq_Value,MCO2PinFreq_Value,OCTOSPIMFreq_Value,PLL2FRACN,PLL2N,PLL2P,PLL2PoutputFreq_Value,PLL2QoutputFreq_Value,PLL2RoutputFreq_Value,PLL3PoutputFreq_Value,PLL3QoutputFreq_Value,PLL3RoutputFreq_Value,PLLM,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLSourceVirtual,PWRFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI2Freq_Value,SDMMC1Freq_Value,SDMMC2Freq_Value,SPI1Freq_Value,SPI2Freq_Value,SPI3Freq_Value,SPI4Freq_Value,SPI5Freq_Value,SPI6Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART12Freq_Value,UART4Freq_Value,UART5Freq_Value,UART7Freq_Value,UART8Freq_Value,UART9Freq_Value,UCPD1outputFreq_Value,USART10Freq_Value,USART11Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USART6Freq_Value,USBFreq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOPLL2OutputFreq_Value,VCOPLL3OutputFreq_Value
    RCC.LPTIM1Freq_Value=250000000
    RCC.LPTIM2Freq_Value=250000000
    RCC.LPTIM3Freq_Value=250000000
    RCC.LPTIM4Freq_Value=250000000
    RCC.LPTIM5Freq_Value=250000000
    RCC.LPTIM6Freq_Value=250000000
    RCC.LPUART1Freq_Value=250000000
    RCC.LSCOPinFreq_Value=32000
    RCC.LSE_VALUE=32768
    RCC.LSIRC_VALUE=32000
    RCC.MCO1PinFreq_Value=64000000
    RCC.MCO2PinFreq_Value=250000000
    RCC.OCTOSPIMFreq_Value=250000000
    RCC.PLL2FRACN=0
    RCC.PLL2N=32
    RCC.PLL2P=1
    RCC.PLL2PoutputFreq_Value=128000000
    RCC.PLL2QoutputFreq_Value=64000000
    RCC.PLL2RoutputFreq_Value=64000000
    RCC.PLL3PoutputFreq_Value=258000000
    RCC.PLL3QoutputFreq_Value=258000000
    RCC.PLL3RoutputFreq_Value=258000000
    RCC.PLLM=5
    RCC.PLLN=100
    RCC.PLLPoutputFreq_Value=250000000
    RCC.PLLQoutputFreq_Value=250000000
    RCC.PLLSourceVirtual=RCC_PLL1_SOURCE_HSE
    RCC.PWRFreq_Value=250000000
    RCC.RNGFreq_Value=48000000
    RCC.RTCFreq_Value=32000
    RCC.SAI1Freq_Value=128000000
    RCC.SAI2Freq_Value=128000000
    RCC.SDMMC1Freq_Value=250000000
    RCC.SDMMC2Freq_Value=250000000
    RCC.SPI1Freq_Value=250000000
    RCC.SPI2Freq_Value=250000000
    RCC.SPI3Freq_Value=250000000
    RCC.SPI4Freq_Value=250000000
    RCC.SPI5Freq_Value=250000000
    RCC.SPI6Freq_Value=250000000
    RCC.SYSCLKFreq_VALUE=250000000
    RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
    RCC.UART12Freq_Value=250000000
    RCC.UART4Freq_Value=250000000
    RCC.UART5Freq_Value=250000000
    RCC.UART7Freq_Value=250000000
    RCC.UART8Freq_Value=250000000
    RCC.UART9Freq_Value=250000000
    RCC.UCPD1outputFreq_Value=16000000
    RCC.USART10Freq_Value=250000000
    RCC.USART11Freq_Value=250000000
    RCC.USART1Freq_Value=250000000
    RCC.USART2Freq_Value=250000000
    RCC.USART3Freq_Value=250000000
    RCC.USART6Freq_Value=250000000
    RCC.USBFreq_Value=48000000
    RCC.VCOInput2Freq_Value=4000000
    RCC.VCOInput3Freq_Value=4000000
    RCC.VCOInputFreq_Value=5000000
    RCC.VCOOutputFreq_Value=500000000
    RCC.VCOPLL2OutputFreq_Value=128000000
    RCC.VCOPLL3OutputFreq_Value=516000000
    VP_GTZC_S_VS_GTZC_Enable.Mode=GTZC_Enable
    VP_GTZC_S_VS_GTZC_Enable.Signal=GTZC_S_VS_GTZC_Enable
    VP_ICACHE_VS_SECURE_ICACHE_REG.Mode=ICACHE_REG_Not_Secured
    VP_ICACHE_VS_SECURE_ICACHE_REG.Signal=ICACHE_VS_SECURE_ICACHE_REG
    VP_NETXDUO_VS_AddonsOoDHCP.Mode=Addons_DHCP_Client
    VP_NETXDUO_VS_AddonsOoDHCP.Signal=NETXDUO_VS_AddonsOoDHCP
    VP_NETXDUO_VS_EthernetOoPhyOoInterface.Mode=LAN8742_Phy_Interface
    VP_NETXDUO_VS_EthernetOoPhyOoInterface.Signal=NETXDUO_VS_EthernetOoPhyOoInterface
    VP_NETXDUO_VS_NXOoCore.Mode=NX_Core
    VP_NETXDUO_VS_NXOoCore.Signal=NETXDUO_VS_NXOoCore
    VP_NETXDUO_VS_NetworkOoInterface.Mode=Ethernet_Interface
    VP_NETXDUO_VS_NetworkOoInterface.Signal=NETXDUO_VS_NetworkOoInterface
    VP_PWR_VS_SECSignals.Mode=Security/Privilege
    VP_PWR_VS_SECSignals.Signal=PWR_VS_SECSignals
    VP_SYS_S_VS_Systick.Mode=SysTick
    VP_SYS_S_VS_Systick.Signal=SYS_S_VS_Systick
    VP_SYS_VS_tim6.Mode=TIM6
    VP_SYS_VS_tim6.Signal=SYS_VS_tim6
    VP_THREADX_VS_RTOSJjThreadXJjCoreJjDefault.Mode=Core_Default
    VP_THREADX_VS_RTOSJjThreadXJjCoreJjDefault.Signal=THREADX_VS_RTOSJjThreadXJjCoreJjDefault
    board=STM32H573I-DK
    boardIOC=true
    isbadioc=false

     

    Passing now to he the third point of my previous post if are able to debug and point to the tx_application_define() and see its execution that confirms that you are in a non secure state because this code is found in the non secure project.


    If I set a breakpoint there, it the execution gets hold. So I do enter this function.

     

    after giving it some thought i recommend you check the memory mapping to see if there is any secure region overlapping an non secure one and i also recommend verifying that the gpio pins of the Ethernet are assigned to the non secure project for sure as well as the other peripherals like the timer.


    I double checked this a few times, everything is assigned to the NS world. (Also see the ioc file above, i hope i did not miss anything)


    check if you can the address of the semaphore blocking your project  if it is in a secure or non secure memory page.

    check if there is any security enabled on the flash like MPU for example .

    waiting for some details on your configuration and code to help you further.


    I can access it. I think the problem here is that the callback function ip_address_change_notify_callback() never gets called (observed by setting a breakpoint at function entry)

    MPU is for both secure and nonsecure disabled (MPU NOT USED). What might be a problem is that i did not change anything for the GTZC config. But i suppose if the problem would be an access violation of some kind the execution would land in the hardfault handler of the secure world, so I dont think that is the case.

    I appreciate your effort to help me! Thank you

    Best,

    funkii

     

    ST Employee
    November 27, 2023

    hELLO @funkii ,

    Could you check if the preemption priority of the Ethernet global interrupt in your msp.c in your non secure project and try and change it  maybe.

    to further pinpoint the problem i recommend you start a new ioc file and implement the project from scratch and try every feature one by one because i think this is related to preemption priorities given by the threadx which can be not inline with the new  NVIC 1 and NVIC 2 attribution causing you to not ever enter the callback were the semaphore is given .

    try and check if there is any interference in the priority attribution between the Ethernet and the threadx defined interrupts .

    BR

    funkiiAuthor
    Explorer II
    November 27, 2023

    Hi @STea,

    i understand that a problem with the Interrupts could be the issue.


    Could you check if the preemption priority of the Ethernet global interrupt in your msp.c in your non secure project and try and change it  maybe.


    I suppose you mean the file stm32h5x_hal_msp.c, i tried to change the following line there:

     HAL_NVIC_SetPriority(ETH_IRQn, 7, 0);

    I used the values 0, 7, and 15 for the second and third argument, sadly with no change.


    to further pinpoint the problem i recommend you start a new ioc file and implement the project from scratch and try every feature one by one because i think this is related to preemption priorities given by the threadx which can be not inline with the new  NVIC 1 and NVIC 2 attribution causing you to not ever enter the callback were the semaphore is given .

    try and check if there is any interference in the priority attribution between the Ethernet and the threadx defined interrupts .


    I'm not really sure if you meant that, but I tried to completely disable the interrupts in a project with disabled TrustZone (that works with enabled Interrupts). After disabling the interrupts, the same behavior can be observed. 

    So i guess my problem of the initial post is somehow caused by an issues with interrupts. 

    Because playing around with the interrupt priority did not change anything, do you have any suggestions what I could do? I could use another networkstack that does not rely on interrupts but only on polling, maybe that fixes that problem (Polling mode might be ugly but could work for my usecase). Do you think that might be an good idea?

    Again, thanks for your help.

    Best,

    funkii

    ST Employee
    November 28, 2023

    Hi @funkii ,

    regarding your suggestion i do not recommend switching to a pooling mode as the interrupts are the cornerstone of any real-time system and this can affect the handling other tasks in the application .

    For now i recommend you further investigate on the priority attribution for the callback and what should trigger it in the project without Trustzone enabled to identify the root cause preventing the callback from executing i will further investigate on this issue i'll keep you updated .

    BR 

    funkiiAuthor
    Explorer II
    November 28, 2023

    Hi @STea ,

    I observed some weird interrupt behavior. 

    I currently have two projects, one without Trustzone, one with Trustzone enabled. They are configured the same way using the steps in the initial post (except assigning everything to the NS world in the TZ enabled version. Also I set the option bytes accordingly if I switch projects).

    If I set a breakpoint in the "stm32h5xx_it.c" file, in the function ETH_IRQHandler(), the execution in the TZ enabled Project never holds, i.e. never reaches this point so the something is definitely wrong with the interrupts... 

    In contrast, in the project without TrustZone, the breakpoint gets reached as expected.

    I'll keep you updated on any news.

    Best,

    funkii

    funkiiAuthor
    Explorer II
    November 29, 2023

    Hi,

    some more observations while debugging further:

    I created three Projects. In every one of them I first cleared the pinout, set the High Speed Clock under the RCC to DIGBYPASS Clock Source, enabled Ethernet to 'RMII' mode, activated the Ethernet global interrupt to preemption priority 7 and set the Pin PG12 to ETH_TXD1. Additionally I set a breakpoint in the stm32h5xx_it.c in the Ethernet Interrupt handler (In the two projects with enabled TrustZone, I set the breakpoints in the 'World' which the Ethernet is assigned to).

    1. TrustZone Disabled. Added the 'HAL_ETH_Start_IT(&heth);' to User Code 2 in main.c
    2. TrustZone Enabled. Assigned ETH to NS World. Added  HAL_ETH_Start_IT(&heth); to User Code 2 in Non Secure main.c
    3. TrustZone Enabled. Assigned ETH to S World.Added  HAL_ETH_Start_IT(&heth); to User Code 2 in Secure main.c

    In 1) and 3), as expected, the breakpoint gets triggered.

    In 2) the breakpoint does not get triggered for some reason. 

    Does anyone have a clue why this is the case? Between switching from TZ enabled/disabled I only set the following option bytes as follows:
    - TZEN=0xB4

    - SECWM1_PSTRT=0x0 SECWM1_PEND=0x7F meaning all 128 pages of Bank1 set as secure

    - SECWM2_PSTRT=0x1 SECWM2_PEND=0x0 meaning no page of Bank2 set as secure, hence Bank2 non-secure

     

    Best, 

    funkii

     

    edit:

    I wrote above that the breakpoint in 1) and 3) gets triggered, which is the case. 

    For some reason the Interrupt gets only called once. The Interrupt is because of an DMA Error, the DMAErrorCode gets set to ETH_DMACSR_RBU and ETH_DMACSR_AIS... Im not really sure what this means, but i guess its some kind of configuration bug because i just call HAL_ETH_Start_IT() and doesnt really matter for the initial problem.

     

     

    funkiiAuthor
    Explorer II
    December 5, 2023

    Hi everyone,

    some more additional information that might be relevant:

    If I activate e.g. the "RCC non-secure global interrupt" in the ioc file, the file "Secure/Core/Inc/partition_stm32h573xx.h" gets changed correctly. -> I attached the git diff

    @@ -386,7 +386,7 @@
     // <o.6> FLASH_IRQn <0=> Secure state
     // <o.7> FLASH_S_IRQn <0=> Secure state
     // <o.8> GTZC_IRQn <0=> Secure state
    -// <o.9> RCC_IRQn <0=> Secure state
    +// <o.9> RCC_IRQn <1=> Non-Secure state^M
     // <o.10> RCC_S_IRQn <0=> Secure state
     // <o.11> EXTI0_IRQn <0=> Secure state
     // <o.12> EXTI1_IRQn <0=> Secure state
    @@ -410,7 +410,7 @@
     // <o.30> GPDMA1_Channel1_IRQn <0=> Secure state
     // <o.31> GPDMA1_Channel2_IRQn <0=> Secure state
     */
    -#define NVIC_INIT_ITNS0_VAL 0x00000000
    +#define NVIC_INIT_ITNS0_VAL 0x00000200^M

    But if I activate the "Ethernet global interrupt", nothing changes in that file. I do not see any Interrupts for the ETH there at all that could be configured by hand.

    Overall between activated and deactivated Interrupt, nothing at all changes in the secure subproject.

     

    I think that might be the problem that I do not receive Interrupts with activated TrustZone. 

    Since I'm not 100% sure that this is the problem, can anyone with more experience confirm that this is the case?

     

     

    funkiiAuthor
    Explorer II
    December 5, 2023

    Hi,

    there seems to be a bug in the code generation:

    I looked up the Ethernet Interrupt Number in the reference manual, which is 106.

    If I modify the Secure/Core/Inc/partition_stm32h573xx.h by hand and set the bits by hand my breakpoint finally gets triggered. In NVIC_INIT_ITNS3_VAL the 12th bit needs to be set.

    #define NVIC_INIT_ITNS3_VAL 0x00000400

    Unfortunately this does not fix my problem...

    The Interrupt gets triggered once, and with a DMA Error. More accurate the Receive Buffer Unavailable (RBU) Bit gets set, together with the Abnormal Interrupt Summary (AIS). The AIS gets always set when RBU gets set.

    I found this description of RBU:

    This bit indicates that the application owns the next descriptor in the Receive list, and the
    DMA cannot acquire it. The Rx process is suspended. To resume processing Rx descriptors,
    the application should change the ownership of the descriptor and issue a Receive Poll
    Demand command. If this command is not issued, the Rx process resumes when the next
    recognized incoming packet is received. In ring mode, the application should advance the
    Receive Descriptor Tail Pointer register of a channel. This bit is set only when the DMA owns
    the previous Rx descriptor.

     

    Anyone got an idea why this is happening? Do i need to change any addresses because I use TrustZone? 

    Best,

    funkii

    ST Employee
    December 6, 2023

    Hello @funkii ,

    When TZ enabled the ETHERNET DMA cannot acquire the descriptors (Tx Descriptor Unavailable / Rx Descriptor Unavailable) placed in SRAM. And thus whether the ETH is placed in secure or not-secure project. so you need to reconfigure the memory layout to get the descriptors out of the protected area .

    BR

    funkiiAuthorAnswer
    Explorer II
    December 7, 2023

    Hi,

    i finally managed to get it working! Thanks @STea for your help, I really appreciate it.

    Steps to get it working:

    Start Board Project with Trustzone enabled
    Firmware Version v1.1.1
    
    Clear pinout
    
    ETH
     Mode RMII
     RxBuffLen 1536
     Set Pin PG12 to ETH_TXD1 (By doing this, PG14 should be cleared)
    
    THREADX
     Core
    
    NETXDUO
     NX Core
     Addons > DHCP > Client
     Network Interfaces > Ethernet interface, Ethernet Phy Interface > LAN8742
     Platform Settings > both lan8742
    
     Enable Interface Capability true
     memory pool size 30 * 1024
     Genreate Init Code true
     IP Instance Thread Size 2 * 1024
     Pool Size in number of Packets 10
     Application Thread Stack Size 2 * 1024
    
    NVIC_NS
     Ethernet global Interupt > Enable, Preemption Priority 7
    
    SYS
     Timebase Source TIM6 (Assign TIM6 to NS before)
    
    RCC
     High speed Clock DIGBYPASS Clock source
    
    GTZC_S
     Block-Based Memory Controller > MPCBB3 (SRAM3) > Memory Privilege Attributes Settings > Configure Memory > from full Not privileged
     (Setting the whole SRAM3 to not priviliged might not be the best idea from an security standpoint if you do other stuff on the board)
    
    Manual change in Secure/Core/Inc/partition_stm32h573xx.h:
    Set the 10th bit in NVIC_INIT_ITNS3_VAL (in my case line 554), so the line should look like this:
    `#define NVIC_INIT_ITNS3_VAL 0x00000400`
    IMPORTANT: After each code-generation check if the bit is still set or overwritten by the code-generation. 
    
    Build and run like normal trustzone project e.g. described here https://github.com/STMicroelectronics/STM32CubeH5/tree/main/Projects/STM32H573I-DK/Examples/GTZC/GTZC_MPCWM_IllegalAccess_TrustZone
    
    You should now be able to ping the board!

     

    One last question: 

    I need to manually change the Pinlayout of ETH to get it working, i.e. assign ETH_TXD1 to PG12.

    Additionally my issue with the Interrupt where i manually need to set a bit in the files.

    Are these known issues or can I report them somewhere?

    Same goes for the MPCBB config, i understand that you might expect developers to do this by themselfs, but a small note when assigning ETH to NonSecure would be really nice as debugging this is kinda pain.

     

    Again, thanks for your help.

    Best,

    funkii