Skip to main content
Graduate II
January 12, 2024
Solved

Azure RTOS Integration in B-U585-IOT2A Bootloader Environment

  • January 12, 2024
  • 10 replies
  • 5511 views

Hello ST, I am trying to integrate ThreadX into TFM_Appli-NonSecure project. Mostly I am able to integrate it and execute but to make a thread run, I have to comment _tx_initialize_low_level(); API in _tx_initialize_kernel_enter() function.

This all work smoothly until I try thread context switching. My initial understanding assumption says pendsv_hander is not getting called.

Could I get some more insight to resolve this issue as there is no direct example available for this.

    This topic has been closed for replies.
    Best answer by Guillaume K

    Hello

    Did you look at X-CUBE-AZURE - Microsoft Azure software expansion for STM32Cube - STMicroelectronics ?

    It has an example of TFM NS application with ThreadX.

    it's in Projects\B-U585I-IOT02A\Applications\TFM_Azure_IoT

    normally you shouldn't comment _tx_initialize_low_level().

    ThreadX requires to use the SysTick interrupt for its own tick (10 ms). it is done in _tx_initialize_low_level.

    There is conflict with STM32 HAL that uses Systick for its own tick (1 ms).

    Solution is to use additional timer TIM6 instead of SysTick for HAL tick.

    See examples with ThreadX (especially Netxduo examples) in STM32 Cube U5.

    Also because it is a TrustZone non-secure app there are some ThreadX sources and #define that must be added in the project.

    tx_thread_secure_stack_allocate/_free.c, txe_thread_secure_stack_allocate/_free.c

    tx_thread_secure_stack_initialise/_build.s

    add define TX_SINGLE_MODE_NON_SECURE=1 at project level for C compiler

    add define TX_SINGLE_MODE_NON_SECURE for assembler files

    see Chapter 2 - Installing ThreadX support for ARMv8-M | Microsoft Learn

     

     

    10 replies

    Visitor II
    January 12, 2024

    Since you suspect that the PendSV handler is not getting called, verify the configuration related to PendSV in your setup. Make sure that the vector table is correctly set up to point to the correct PendSV handler function.

    NitinAuthor
    Graduate II
    January 12, 2024

    Thanks for replying, everything seems correct to me. One of the main reason behind this can be some TF-M violation.

    NitinAuthor
    Graduate II
    January 12, 2024

    To be precise, after this call MCU is getting reset in loop

    /* Set PendSV to invoke ThreadX scheduler. */

    *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);

    ST Employee
    January 12, 2024

    Hello

    Did you look at X-CUBE-AZURE - Microsoft Azure software expansion for STM32Cube - STMicroelectronics ?

    It has an example of TFM NS application with ThreadX.

    it's in Projects\B-U585I-IOT02A\Applications\TFM_Azure_IoT

    normally you shouldn't comment _tx_initialize_low_level().

    ThreadX requires to use the SysTick interrupt for its own tick (10 ms). it is done in _tx_initialize_low_level.

    There is conflict with STM32 HAL that uses Systick for its own tick (1 ms).

    Solution is to use additional timer TIM6 instead of SysTick for HAL tick.

    See examples with ThreadX (especially Netxduo examples) in STM32 Cube U5.

    Also because it is a TrustZone non-secure app there are some ThreadX sources and #define that must be added in the project.

    tx_thread_secure_stack_allocate/_free.c, txe_thread_secure_stack_allocate/_free.c

    tx_thread_secure_stack_initialise/_build.s

    add define TX_SINGLE_MODE_NON_SECURE=1 at project level for C compiler

    add define TX_SINGLE_MODE_NON_SECURE for assembler files

    see Chapter 2 - Installing ThreadX support for ARMv8-M | Microsoft Learn

     

     

    NitinAuthor
    Graduate II
    January 18, 2024

    Thanks Guillaume for the detailed reply.

    Things are much clear now. But I still have some problem to be resolved(may be last one). Actually I have some issue with below statement from the link provided.

    "The file tx_thread_secure_stack.c must be added to the secure application."

    It's not clear to me actually and I am getting undefined reference for all the functions defined in this file.

    (.text+0x60): undefined reference to `_tx_thread_secure_stack_context_save'
    (.text+0x90): undefined reference to `_tx_thread_secure_stack_context_restore'
    (.text+0xfe): undefined reference to `_tx_thread_secure_mode_stack_allocate'
    (.text+0x110): undefined reference to `_tx_thread_secure_mode_stack_free'
    (.text+0x120): undefined reference to `_tx_thread_secure_mode_stack_initialize'

    Moreover Projects\B-U585I-IOT02A\Applications\TFM_Azure_IoT is not directly compiling. So not able to take much help from it.

    ST Employee
    January 18, 2024

    Hello Nitin

    regarding the missing functions you mention (_tx_thread_secure_stack_context_save, etc), did you define TX_SINGLE_MODE_NON_SECURE for C compiler AND also for the assembler ?

    what IDE/compiler are you using ?

    In fact, some of the tx_thread_secure_* files are not really used in case of non-secure application. I guess Microsoft suggest to put everything in the project in case you switch it to secure side.

     

    - What do you mean by "Projects\B-U585I-IOT02A\Applications\TFM_Azure_IoT is not directly compiling. " ?

    In this package, several other projects must be compiled before the non secure application (bootloader, TFM secure application, etc).

    If you use IAR EWARM , you must run the batch build (F8) that will compile the project in correct order.

    If you use STM32CubeIDE, in TFM_Appli project normally there are references to other projects that will make them compile before. You have to import in your workspace all the STM32CubeIDE projects under Projects\B-U585I-IOT02A\Applications\TFM_Azure_IoT .

    If you are using STM32CubeIDE version 1.14.0 , try to switch to 1.14.1 released recently. Version 1.14.1 corrects problems when running shell commands from STM32CubeIDE. 

     

    ST Employee
    January 12, 2024

    Hello Nitin,

    on top of Guillaume's feedback, one other point to check is relative to interrupt vector pointer.

    In _tx_initialize_low_level you reference g_pfnVectors (at lines 527 and 538)

     /* Setup Vector Table Offset Register. */
     MOV r0, #0xE000E000 // Build address of NVIC registers
     LDR r1, =g_pfnVectors // Pickup address of vector table
     STR r1, [r0, #0xD08] // Set vector table address
    
     /* Enable the cycle count register. */
     LDR r0, =0xE0001000 // Build address of DWT register
     LDR r1, [r0] // Pickup the current value
     ORR r1, r1, #1 // Set the CYCCNTENA bit
     STR r1, [r0] // Enable the cycle count register
    
     /* Set system stack pointer from vector value. */
     LDR r0, =_tx_thread_system_stack_ptr // Build address of system stack pointer
     LDR r1, =g_pfnVectors // Pickup address of vector table
     LDR r1, [r1] // Pickup reset stack pointer
     STR r1, [r0] // Save system stack pointer

     

    But in actual interrupt vectors definition in startup_stm32u5xx.c of non secure application example, you have 

    extern const pFunc __VECTOR_TABLE[];
     const pFunc __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = {
     (pFunc)(&__INITIAL_SP), /* Initial Stack Pointer */
     Reset_Handler, /* Reset Handler */
     NMI_Handler, /* -14: NMI Handler */

    So you probably need to align the naming.

    I didn't have time to double check but worth trying because your issue seems related to this

    Best regards

    Jocelyn

    NitinAuthor
    Graduate II
    January 18, 2024

    Thanks Jocelyn, you got it correctly. g_pfnVectors was one of the issue and it got resolved after replacing with __Vectors.

    Graduate II
    January 12, 2024

    @Nitin Why do not you use the original Arm TF-M solution?
    The reason I ask is because I just spend entire week testing TFM and SBSFU apps, going thorough all the docs to make sense out of it and then I learned that TFM has been recently removed from GitHub and, I assume, will not be supported anymore. Probably the same is true for SBSFU. See issue #37 & issue #38.

    TF-M solution 2.0 is a state-of-the-art solution, contains preconfigured profiles for the following ST MPUs/boards:
    b_u585i_iot02a
    nucleo_l552ze_q
    stm32h573i_dk
    stm32l562e_dk
    It is actively maintained (new commits everyday), is highly configurable, has own community supporting it, current roadmap and well documented releases  - which is not to be said about ST TFM app, probably based on relatively old TF-M 1.3. There is just one thing, as I found out, to understand how TF-M is supposed to be used one needs to study MCUboot design and PSA Certified Firmware Update API documents first (TF-M is really MCUBoot extension).

    In my view, it is actually good that ST stopped supporting TFM because it clearly had no commitment, capacity and motivation to do it well enough. This effort could be much better spend on supporting the original Arm TF-M and own HAL. Maturity-wise ST is still where Microsoft used to be during Steve Ballmer era, still dreaming of total market domination, trying to provide own software everywhere (e.g. own Internet Explorer renderer) instead of focusing on HAL quality while contributing and collaborating anywhere else, where it would make much more sense.
    I would happily pay 50% more for ST MCUs and would not even look at alternatives if they came with high quality HAL and examples, but currently this is not an option.

    Just my 3 cents.

    Super User
    January 14, 2024

    @TDJ ST does support trustedfirmware.org, they are even listed as a Platinum member.  https://www.trustedfirmware.org/join/

     

     

    Graduate II
    January 15, 2024

    @Pavel A. Correct, there is hope, on the list of TF-M maintainers there is one ST employee.

    NitinAuthor
    Graduate II
    January 18, 2024

    Hi Guillaume, I was doing one silly mistake. Actually I didn't included TX_SINGLE_MODE_NON_SECURE for the assembler.

     

    Now,

    1. _tx_initialize_low_level() is not commented.

    Nitin_5-1705598809586.png

     

    1. using additional timer TIM6 instead of SysTick for HAL tick.

    Nitin_6-1705598809595.png

     

    Nitin_7-1705598809598.png

     

     

    1. TX_SINGLE_MODE_NON_SECURE=1 is included in C compiler and assembler.

    Nitin_8-1705598809600.png

     

    Nitin_10-1705601702100.png

     

     

    tx_thread_secure_stack_allocate/_free.c, txe_thread_secure_stack_allocate/_free.c, tx_thread_secure_stack_initialise/_build.s included(as I am able to compile my code.

     

    I followed all these steps but still my application is not moving past

    *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);

    And device is resetting continously. Is there anything I am still missing!!!

     

    Only doubt I have is, “The file tx_thread_secure_stack.c must be added to the secure application.” I have not added this file into secure area.

    NitinAuthor
    Graduate II
    January 19, 2024

    Hello ST, please guide me to resolve this issue. Is PendSV priority has to be changed to trigger the interrupt?

    ST Employee
    January 22, 2024

    Not sure why it doesn't work. I don't have your full project. It could be anything.

    Did you compare with what is done in X-Cube-Azure package ?

    Don't touch PendSV priority. it should be 15 (lowest).

    TIM6 should be higher priority than PendSV (so for example 14).

     

    NitinAuthor
    Graduate II
    January 22, 2024

    Hi Guillaume, I have commented here in this thread. This thread is most relevant to my current blockage. If you could look into this.

    I don't this their much work done on STM32U585 series, specially on TFM + BL setup. We are expecting active support from ST on this.

     

    https://community.st.com/t5/stm32cubemx-mcus/stm32cubeide-1-7-mcu-package-l4-series-1-17-vtor-is-not/td-p/220563/page/2

    ST Employee
    January 22, 2024

    The thread you mention talks about customisation of interrupt vectors table address on STM32L4.

    It is different on STM32U5 in TFM environment.

    Do you have in your code the function SystemInit() in system_stm32u5xx.c? could you compare your code with reference TFM implementation in Projects/B-U585I-IOT02A/Applications/TFM/TFM_Appli/NonSecure/Core/Src/system_stm32u5xx.c, function SystemInit():

    There should be only these lines:

    void SystemInit(void)
    {
    /* FPU settings ------------------------------------------------------------*/
    #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */
    #endif
    }

    when comparing to "standard" system_stm32u5xx.c some code is removed.  the SCB->VTOR register is not modified directly in this file. also some clock settings are not changed. If the lines modifying SCB->VTOR are present then it could explain the problem.