cancel
Showing results for 
Search instead for 
Did you mean: 

SMCubeIDE Live Expressions - Incorrect Data Framing (Weird)

Garnett.Robert
Senior III

Hi,

 

I have a functioning project that fully compiles with only three warnings, but when I debug it and examine C structures in the live expressions viewer the the data (GovTrimControl_P structure ) appears to be offset by 4 bytes, yet the memory browser shows the correct values and when the mouse hovers over a value that value is correct:

 

Snag_190db9f0.png

 

Snag_190ed747.png

Snag_191550df.png

 

The Build Analyser also reports the address of GovTrimControl_P  correctly

Snag_1918f31c.png

Compile Problem Output:

Snag_1916f2f6.png

The values for the GovTrimControl_P structure are set at bootup to:

 

 

 

/* Parameters (default storage) */
struct P_GovTrimControl_T_
{
  real32_T FreqSP;                     /* Variable: FreqSP */                              
  real32_T kD;                         /* Variable: kD */
  real32_T kI;                         /* Variable: kI */                                       
  real32_T kN;                         /* Variable: kN */
  real32_T kP;                         /* Variable: kP */
};

typedef struct P_GovTrimControl_T_ P_GovTrimControl_T;

/* Block parameters (default storage) */
P_GovTrimControl_T GovTrimControl_P =
{
  /* Variable: FreqSP */
  50.0F,

  /* Variable: kD */
  2.0F,

  /* Variable: kI */
  20.0F,

  /* Variable: kN */
  2.0F,

  /* Variable: kP */
  30.0F
};

 

 

The problem also occurs with another constant array where the Live Expression viewer reports incorrect framing of the underlying data.

I am running STM32CubeIDE Version

Version: 1.16.1

Build: 22882_20240916_0822 (UTC)

 

On an STM32H750B-DK Discovery kit,

 

I have attached the Linker Script File, startup file and video in the hope this might shed some light on the issue. The video shows the Backup ram memory which has the GovTrimControl_P data copied into it. The data shows the correct framing in the browser, but not in the Live Expression viewer:

 

Snag_192b6556.png

 The backup ram copy function and its use are shown below:

 

 

 

void backupRamStartup(uint16_t bypassBtnState,
uint32_t code,									uint32_t* ramCode,
void* ramAddr,
void* parameters,
uint16_t size)
{
	if((bypassBtnState == 1) || (*ramCode != code))
	{
		/* The user is setting the defaults or the backupRam is empty */
		*ramCode = code;
		memcpy(ramAddr, parameters, size);
		return;
	}
	/* The backup ram contents are used to set the parameters*/
	memcpy(&parameters, &ramAddr, size);
}

/* Useage */

backupRamStartup(  								        HAL_GPIO_ReadPin(PC13_PB_DEFAULT_SET_GPIO_Port, 
PC13_PB_DEFAULT_SET_Pin),
0xC0AD1234,
&backupRAMValidationCode,
&backupRam,
&GovTrimControl_P,
sizeof(GovTrimControl_P));

 

 

 

I have never seen this occur in any of my other similar projects with older versions of the IDE.

 

Has anyone else seen this problem

 

Kind Regards

Rob

 

 

 

 

/* LINKER SCRIPT */
/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1);	/* end of "RAM_D1" Ram type memory */

_Min_Heap_Size = 0x1000;	/* required amount of heap  */
_Min_Stack_Size = 0x1000;	/* required amount of stack */

/* Memories definition */
MEMORY
{
  DTCM_STACK    	(xrw)   : ORIGIN = 0x20000000,   		LENGTH = _Min_Heap_Size + _Min_Stack_Size
  DTCM_MISC	   		(xrw)    : ORIGIN = 0x20002000,   		LENGTH = 120K
  ITCMRAM      		(xrw)    : ORIGIN = 0x00000000,   		LENGTH = 64K
  RAM_D1       		(xrw)    : ORIGIN = 0x24000000,   		LENGTH = 512K
  RAM_D2       		(xrw)    : ORIGIN = 0x30000000,   		LENGTH = 288K
  RAM_D3       		(xrw)    : ORIGIN = 0x38000000,   		LENGTH = 64K
  SDRAM_FB     		(xrw)    : ORIGIN = 0xD0000000,   		LENGTH = 765K
  SDRAM_USER   		(xrw)    : ORIGIN = 0xD0000000 + 765K,  LENGTH = 8M - 765K
  FLASH	       		(xr)     : ORIGIN = 0x90000000,   		LENGTH = 2048K
  ASSETS_FLASH 		(r)      : ORIGIN = 0x90200000,   		LENGTH = 126M
  BOOTLOADER   		(xrw)    : ORIGIN = 0x08000000,   		LENGTH = 128k
  VBAT_SRAM_CODE	(xrw)    : ORIGIN = 0x38800000,  		LENGTH = 4
  VBAT_SRAM	   		(xrw)    : ORIGIN = 0x38800000 + 4,   	LENGTH = 4K - 4
}

TARGET(binary) /* specify the file format of binary file */
INPUT (../../ExtMem_Boot/bootloader.bin) /* bootloader bin file path (relative to the output folder)*/
OUTPUT_FORMAT(default) /* restore the out file format */

/* Sections */
SECTIONS
{
  .bootloader :
  {
    . = ALIGN(4);
    KEEP(../../ExtMem_Boot/bootloader.bin)
  } > BOOTLOADER

  /* The startup code into "FLASH" Rom type memory */
  .isr_vector :
  {
    __ICFEDIT_intvec_start__ = .;
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

  /* The program code and other data into "FLASH" Rom type memory */
  .text :
  {
    . = ALIGN(4);
    *(.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(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH

  /* Constant data into "FLASH" Rom type memory */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH

  .ARM.extab (READONLY) : {
    . = ALIGN(4);
    *(.ARM.extab* .gnu.linkonce.armextab.*)
    . = ALIGN(4);
  } >FLASH

  .ARM (READONLY) :  {
    . = ALIGN(4);
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
    . = ALIGN(4);
  } >FLASH

  .preinit_array  (READONLY)   :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
    . = ALIGN(4);
  } >FLASH

  .init_array (READONLY) :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
    . = ALIGN(4);
  } >FLASH

  .fini_array (READONLY) :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
    . = ALIGN(4);
  } >FLASH

  /* Used by the startup to initialize data */
  _sidata = LOADADDR(.data);

  /* Initialized data sections into "RAM_D1" Ram type memory */
  .data :
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */

  } >RAM_D1 AT> FLASH

  /* Uninitialized data section into "RAM_D1" Ram type memory */
  . = 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;
  } >RAM_D1

  /* User_heap_stack section, used to check that there is enough "RAM_D1" Ram  type memory left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >DTCM_STACK


  .DTCM_MISC : {
  . = ALIGN(4);
  _sDTCM_MISC = .;
  __sDTCM_MISC__ = _sDTCM_MISC;
  *(.DTCM_MISC) /* All nominated variables */
  	. = ALIGN(4);
  _eDTCM_MISC = .;
  __eDTCM_MISC__ = _eDTCM_MISC;
  } >DTCM_MISC


  .VBAT_SRAM_CODE (NOLOAD) :  {
  . = ALIGN(4);
  _sVBAT_SRAM_CODE = .;
  __sVBAT_SRAM_CODE__ = _sVBAT_SRAM_CODE;
  *(.VBAT_SRAM_CODE) /* All nominated variables */
  	. = ALIGN(4);
  _eVBAT_SRAM_CODE = .;
  __eVBAT_SRAM_CODE__ = _eVBAT_SRAM_CODE;
  } >VBAT_SRAM_CODE


  .VBAT_SRAM (NOLOAD) :  {
  . = ALIGN(4);
  _sVBAT_SRAM = .;
  __sVBAT_SRAM__ = _sVBAT_SRAM;
  *(.VBAT_SRAM) /* All nominated variables */
  	. = ALIGN(4);
  _eVBAT_SRAM = .;
  __eVBAT_SRAM__ = _eVBAT_SRAM;
  } >VBAT_SRAM


  /* Remove information from the compiler libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }



  FontFlashSection :
  {
    *(FontFlashSection FontFlashSection.*)
    *(.gnu.linkonce.r.*)
    . = ALIGN(0x4);
  } >ASSETS_FLASH

  TextFlashSection :
  {
    *(TextFlashSection TextFlashSection.*)
    *(.gnu.linkonce.r.*)
    . = ALIGN(0x4);
  } >ASSETS_FLASH

  ExtFlashSection :
  {
    *(ExtFlashSection ExtFlashSection.*)
    *(.gnu.linkonce.r.*)
    . = ALIGN(0x4);
  } >ASSETS_FLASH

  BmpCacheSection (NOLOAD) : { *(BmpCacheSection) } >SDRAM_FB
  TouchGFX_Framebuffer (NOLOAD) : { *(TouchGFX_Framebuffer) } >SDRAM_FB
  TouchGFX_Framebuffer1 (NOLOAD) : { *(TouchGFX_Framebuffer1) } >SDRAM_FB
  TouchGFX_Framebuffer2 (NOLOAD) : { *(TouchGFX_Framebuffer2) } >SDRAM_FB
  Video_RGB_Buffer (NOLOAD) : { *(Video_RGB_Buffer) } >SDRAM_FB

}

/* Start-up code */

  .syntax unified
  .cpu cortex-m7
  .fpu softvfp
  .thumb

.global  g_pfnVectors
.global  Default_Handler

/* start address for the initialization values of the .data section. 
defined in linker script */
.word  _sidata
/* start address for the .data section. defined in linker script */  
.word  _sdata
/* end address for the .data section. defined in linker script */
.word  _edata
/* start address for the .bss section. defined in linker script */
.word  _sbss
/* end address for the .bss section. defined in linker script */
.word  _ebss
/* stack used for SystemInit_ExtMemCtl; always internal RAM used */

/**
 * @brief  This is the code that gets called when the processor first
 *          starts execution following a reset event. Only the absolutely
 *          necessary set is performed, after which the application
 *          supplied main() routine is called. 
 *   None
 * @retval : None
*/

    .section  .text.Reset_Handler
  .weak  Reset_Handler
  .type  Reset_Handler, %function
Reset_Handler:  
  ldr   sp, =_estack      /* set stack pointer */

/* Copy the data segment initializers from flash to SRAM */  
  movs  r1, #0
  b  LoopCopyDataInit

CopyDataInit:
  ldr  r3, =_sidata
  ldr  r3, [r3, r1]
  str  r3, [r0, r1]
  adds  r1, r1, #4
    
LoopCopyDataInit:
  ldr  r0, =_sdata
  ldr  r3, =_edata
  adds  r2, r0, r1
  cmp  r2, r3
  bcc  CopyDataInit
  ldr  r2, =_sbss
  b  LoopFillZerobss
/* Zero fill the bss segment. */  
FillZerobss:
  movs  r3, #0
  str  r3, [r2], #4
    
LoopFillZerobss:
  ldr  r3, = _ebss
  cmp  r2, r3
  bcc  FillZerobss

 

 

 

 

 

5 REPLIES 5
Garnett.Robert
Senior III

Additional

 

I made a very small project with the same data structure as GovTrimControl_P and the mis-framing did not occur.

 

I then thought maybe the data appeared misaligned to the IDE which only happens with a big project so I added __attribute__((__aligned__(4))) to my variables and voila it is fixed.

 

backupRam_t __attribute__((__aligned__(4))) __attribute__((section (".VBAT_SRAM"))) backupRam;

And

P_GovTrimControl_T __attribute__((__aligned__(4))) GovTrimControl_P =
{
  /* Variable: FreqSP
   * Referenced by: '<S1>/Constant'
   */
  50.0F,...

 

Of course the data isn't misaligned as the data are floats, the IDE just thinks it is.

 

So there is a bug in the IDE, that only seems to appear in non-trivial projects.

 

Adding the alignment seems to work so All is Good.

 

 

The problem re-occured so it seems the attribute  aligned isn't the answer.

What a pain.

Karl Yamashita
Lead III

I tried your data structure on a Nucleo-G431KB and didn't see any issues after several debugging tries. The Live Expression looked good.

 

I then grabbed a STM32H750B-DK and copied over the code from the G431.

On the first debug, the FreqSP showed 30. Somewhat similar to what you show. Unfortunately i didn't get screen grab of it.

 

I then added an attribute to align the data structure and debugged again. The data looked normal.

KarlYamashita_0-1727510757802.png

 

I removed the attribute and I tried debugging at least 15 times. I can't seem to produce the same issue. Maybe it was just a random one time fluke? 

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

Hi,

 

I think you are correct; it is a random bug.  I also noticed that on occasions live expressions reports booleans as numbers other than 0 or 1, this might be another peculiarity or just the same framing bug.

 

In any event although it is a nuisance as long as people are aware of it they can always check with the memory browser which is excellent as it can display the data in all the different data formats.

 

Kind Regards

Rob

I've had this happen too. In my case setting a breakpoint, deleting the live expressions and adding them again fixed it.

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.