cancel
Showing results for 
Search instead for 
Did you mean: 

AZURE RTOS (ThreadX) with SBSFU WatchDog reset

matteochen
Associate II

Hello!

I am merging the user app provided in the default sbsfu package with my custom application that is based on the ThreadX kernel. The FW boots normally but every time the kernel finishes ("VOID _tx_initialize_kernel_enter(VOID)") the "tx_application_define(_tx_initialize_unused_memory)" step and while entering the scheduler call the FW freezes for 1 second so it reboots with a message that a watchdog has triggered the reboot.

VOID  _tx_initialize_kernel_enter(VOID)
{
 
    /* Determine if the compiler has pre-initialized ThreadX.  */
    if (_tx_thread_system_state != TX_INITIALIZE_ALMOST_DONE)
    {
 
        /* No, the initialization still needs to take place.  */
 
        /* Ensure that the system state variable is set to indicate 
           initialization is in progress.  Note that this variable is 
           later used to represent interrupt nesting.  */
        _tx_thread_system_state =  TX_INITIALIZE_IN_PROGRESS;
 
        /* Call any port specific preprocessing.  */
        TX_PORT_SPECIFIC_PRE_INITIALIZATION
 
        /* Invoke the low-level initialization to handle all processor specific
           initialization issues.  */
        _tx_initialize_low_level();
    
        /* Invoke the high-level initialization to exercise all of the 
           ThreadX components and the application's initialization 
           function.  */
        _tx_initialize_high_level();
 
        /* Call any port specific post-processing.  */
        TX_PORT_SPECIFIC_POST_INITIALIZATION
    }
 
    /* Optional processing extension.  */
    TX_INITIALIZE_KERNEL_ENTER_EXTENSION
 
    /* Ensure that the system state variable is set to indicate 
       initialization is in progress.  Note that this variable is 
       later used to represent interrupt nesting.  */
    _tx_thread_system_state =  TX_INITIALIZE_IN_PROGRESS;
 
    /* Call the application provided initialization function.  Pass the
       first available memory address to it.  */
    tx_application_define(_tx_initialize_unused_memory);
 
   printf("\r\n\t  DB 1");
 
    /* Set the system state in preparation for entering the thread 
       scheduler.  */
    _tx_thread_system_state =  TX_INITIALIZE_IS_FINISHED;
 
   printf("\r\n\t  DB 2");
 
    /* Call any port specific pre-scheduler processing.  */
    TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION
 
   printf("\r\n\t  DB 3");
 
    /* Enter the scheduling loop to start executing threads!  */
    _tx_thread_schedule();
 
#ifdef TX_SAFETY_CRITICAL
 
    /* If we ever get here, raise safety critical exception.  */
    TX_SAFETY_CRITICAL_EXCEPTION(__FILE__, __LINE__, 0);
#endif
}

("DB 3" is printed by the MCU)

Do you have any suggestion? The default user app works well on my board (stm32h723) and I have compiled all the threadx assembler files.

Thanks!

2 REPLIES 2

Hello @matteochen​ ,

Can you please provide the linker file for further check ?

Otherwise, try to increase the stack memory size and see what happens.

BeST Regards,

Walid

Hello @Walid ZRELLI​ ,

thank you for your responce, I'll attach you the linker. I have left all the field untouched besided two memory sections (.tcp_sec and .nx_data) that have been added to manage NetxDuo packages

/*
*****************************************************************************
**
**  File        : LinkerScript.ld
**
**  Abstract    : Linker script for STM32H753ZITx Device with
**                2048KByte FLASH, 128KByte RAM (old comment)
**
**                Set heap size, stack size and stack location according
**                to application requirements.
**
**                Set memory bank area and size if external memory is used.
**
**  Target      : STMicroelectronics STM32
**
**
**  Distribution: The file is distributed as is, without any warranty
**                of any kind.
**
**  (c)Copyright Ac6.
**  You may use this file as-is or modify it according to the needs of your
**  project. Distribution of this file (unmodified or modified) is not
**  permitted. Ac6 permit registered System Workbench for MCU users the
**  rights to distribute the assembled, compiled & linked contents of this
**  file as part of an application binary file, provided that it is built
**  using the System Workbench for MCU toolchain.
**
*****************************************************************************
*/
 
/* Entry Point */
ENTRY(Reset_Handler)
 
/* Highest address of the user mode stack */
/* _estack = 0x20020000; */
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1);
 
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x800; /* required amount of stack */
 
INCLUDE mapping_fwimg.ld
INCLUDE mapping_sbsfu.ld
 
/* Specific ROM/RAM UserApp definition */
__ICFEDIT_intvec_start__  = __ICFEDIT_SLOT_Active_1_start__    + 0x400;  /* Cortex-M7: align the init vectors on 0x400 */
APPLI_region_ROM_start    = __ICFEDIT_SLOT_Active_1_start__    + VECTOR_SIZE + 0x400;
APPLI_region_ROM_length   = __ICFEDIT_SLOT_Active_1_end__    - APPLI_region_ROM_start + 1;
APPLI_region_RAM_start    = __ICFEDIT_SE_region_RAM_end__ + 1;
APPLI_region_RAM_length   = 0x20020000 - APPLI_region_RAM_start;
 
/* Specify the memory areas */
MEMORY
{
 ISR_VECTOR (rx)   : ORIGIN = __ICFEDIT_intvec_start__, LENGTH = VECTOR_SIZE
 APPLI_region_ROM  : ORIGIN = APPLI_region_ROM_start, LENGTH = APPLI_region_ROM_length
 APPLI_region_RAM  : ORIGIN = APPLI_region_RAM_start, LENGTH = APPLI_region_RAM_length
 RAM_D1  (xrw)     : ORIGIN = 0x24000000,   LENGTH = 320K
}
 
/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  .isr_vector :
  {
    . = ALIGN(8);
    KEEP(*(.isr_vector)) /* Startup code */
    FILL(0);
    . = ORIGIN(ISR_VECTOR) + LENGTH(ISR_VECTOR) - 1;
    BYTE(0)
    . = ALIGN(8);
  } >ISR_VECTOR
 
  .SE_IF_Code : {
  KEEP(*se_interface_app.o (.text .text*))
  } >SE_IF_region_ROM
 
  /* The program code and other data goes into FLASH */
  .text :
  {
    . = ALIGN(8);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)
 
    KEEP (*(.init))
    KEEP (*(.fini))
 
    . = ALIGN(8);
    _etext = .;        /* define a global symbols at end of code */
  } >APPLI_region_ROM
 
  /* Constant data goes into FLASH */
  .rodata :
  {
    . = ALIGN(8);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(8);
  } >APPLI_region_ROM
 
  .ARM.extab   :
  {
  . = ALIGN(8);
  *(.ARM.extab* .gnu.linkonce.armextab.*)
  . = ALIGN(8);
  } >APPLI_region_ROM
  .ARM : {
	. = ALIGN(8);
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
	. = ALIGN(8);
  } >APPLI_region_ROM
 
  .preinit_array     :
  {
	. = ALIGN(8);
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
	. = ALIGN(8);
  } >APPLI_region_ROM
 
  .init_array :
  {
	. = ALIGN(8);
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
	. = ALIGN(8);
  } >APPLI_region_ROM
  .fini_array :
  {
	. = ALIGN(8);
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
	. = ALIGN(8);
  } >APPLI_region_ROM
 
  /* used by the startup to initialize data */
  _sidata = LOADADDR(.data);
 
  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data :
  {
    . = ALIGN(8);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */
 
    . = ALIGN(8);
    _edata = .;        /* define a global symbol at data end */
  } >APPLI_region_RAM AT >APPLI_region_ROM
 
  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)
 
    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >APPLI_region_RAM
 
  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >APPLI_region_RAM
 
  /* ETH descriptors */ 
  .tcp_sec (NOLOAD) :  
  { 
 
    . = ABSOLUTE(0x24019000);
    *(.RxDecripSection) 
 
    . = ABSOLUTE(0x24019060);
    *(.TxDecripSection) 
 
  } >RAM_D1 AT> APPLI_region_ROM 
 
  /* Memory pools */
  .nx_data (NOLOAD): 
  { 
    *(.NetworkPoolSection) 
    *(.UserPoolSection) 
 
  } >RAM_D1 AT >APPLI_region_ROM 
 
  /* Extra ROM section (last one) to make sure the binary size is a multiple of the AES block size (16 bytes) and H7 flash writing unit (32 bytes)*/
  .align32 :
  {
    . = . + 1;         /* _edata=. is aligned on 8 bytes so could be aligned on 32 bytes: add 1 byte gap */
    . = ALIGN(32) - 1; /* increment the location counter until next 32 bytes aligned address (-1 byte)   */
    BYTE(0);           /* allocate 1 byte (value is 0) to be a multiple of 32 bytes                      */
  } > APPLI_region_ROM
 
  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }
 
  .ARM.attributes 0 : { *(.ARM.attributes) }
}

 I have tried to refresh the watchdog before calling the scheduler but the result is the same.

Thank you!