cancel
Showing results for 
Search instead for 
Did you mean: 

STMCubeIDE wrong variable size shown in Build Analyzer

SOgal.1
Associate II

Hi, I am using an STM32F401CCU6 for a FreeRTOS project. My problem is that a variable shows up in the Build Analyzer as 64B instead of 80B.

I am using some LoRa libraries. For simplicity, I will refer only to the information I think is relevant for the problem.

-- I have a type called lora_status_t defined as follows:

typedef struct {
	uint8_t opmode;
	uint8_t version;
	uint8_t sync_word;
 
	// pa config
	uint8_t pa_config;
	uint8_t pa_select;
	float max_power;
	float output_power_dbm;
 
	// modem config 1
	uint8_t modem_config_1;
	float bw;
	uint8_t implicit;
	float coding_rate;
 
	// modem config 2
	uint8_t modem_config_2;
	uint16_t spreading_factor;
	uint8_t tx_continuous_mode;
	uint8_t rx_payload_crc_on;
 
	// modem config 3
	uint8_t modem_config_3;
 
 
 
	// Lora Page registers
	uint8_t fifoAddrPtr;
	uint8_t fifoTxBaseAddr;
	uint8_t fifoRxBaseAddr;
	uint8_t fifoRxCurrAddr;
 
	uint8_t fifoRxBytesNb;
	uint16_t validHeaderCnt;
	uint16_t validPacketCnt;
} lora_status_t;

-- I have another type, lora_sx127x which contains some variables, including one lora_status_t.

// LORA definition
typedef struct {
  // SPI parameters
  SPI_HandleTypeDef  *spi;
  GPIO_TypeDef       *nss_port;
 
  uint32_t            spi_timeout;
  // Operating frequency, in Hz
  uint32_t            frequency;
  // Output PIN (module internal, not related to your design)
  // Can be one of PA_OUTPUT_PA_BOOST / PA_OUTPUT_RFO
  uint32_t            pa_mode;
  // Base FIFO addresses for RX/TX
  uint8_t             tx_base_addr;
  uint8_t             rx_base_addr;
 
  uint16_t            nss_pin;
  GPIO_TypeDef       *reset_port;
  uint16_t            reset_pin;
  lora_status_t		  status;
} lora_sx127x;

-- sizeof(lora_status_t) = 48

-- sizeof(lora_sx127x) = 80

Buil Analyzer instead shows it as 68B. This means all debugging using STMCubeIDE in that zone is lacking 12B, which means, for example, that Live Expressions of expressions right after the (lora_sx127x)lora variable show wrong values.

Build Analyzer, under .bss:

0693W00000aJ806QAC.png 

This is an extraction of the .map generated from the Debug:

...
 .bss.xIdleTaskTCBBuffer
                0x00000000200011a8       0xb4 ./Core/Src/freertos.o
 .bss.xIdleStack
                0x000000002000125c      0x200 ./Core/Src/freertos.o
 .bss.lora      0x000000002000145c       0x50 ./Core/Src/main.o
                0x000000002000145c                lora
 .bss.hrtc      0x00000000200014ac       0x20 ./Core/Src/rtc.o
                0x00000000200014ac                hrtc
 .bss.hspi1     0x00000000200014cc       0x58 ./Core/Src/spi.o
                0x00000000200014cc                hspi1
 .bss.__sbrk_heap_end
                0x0000000020001524        0x4 ./Core/Src/sysmem.o
 .bss.uwTick    0x0000000020001528        0x4 ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.o
                0x0000000020001528                uwTick
...

It interesting that the .bss.lora variable is actually 0x50 = dec80 in size in the memory map! A curious thing is that I cannot find the variables changeDateTime_External_flag and changeDateTime_External_dateTime in the map file. I checked that the build analyzer shows the correct date and time of the elf file being analyzed.

Thanks for your time,

S.

1 ACCEPTED SOLUTION

Accepted Solutions
SOgal.1
Associate II

I have solved the problem. There was another header being included before the definition of the LoRa libraries. This header contained #pragma pack(1) without at #pragma pack(4) at the end. Adding a #pragma pack(4) at the end of that header fixed the problem.

Open questions:

  • if the pragma pack(1) affected the LoRa structure definition packing, why does sizeof() shows 80 for lora_sx127x?
  • why does the structure dereference operator (->) used in assignments acts always as if the structure was 4byte aligned and not 1byte aligned in the case of 1byte aligned structs?

View solution in original post

2 REPLIES 2
SOgal.1
Associate II

I have solved the problem. There was another header being included before the definition of the LoRa libraries. This header contained #pragma pack(1) without at #pragma pack(4) at the end. Adding a #pragma pack(4) at the end of that header fixed the problem.

Open questions:

  • if the pragma pack(1) affected the LoRa structure definition packing, why does sizeof() shows 80 for lora_sx127x?
  • why does the structure dereference operator (->) used in assignments acts always as if the structure was 4byte aligned and not 1byte aligned in the case of 1byte aligned structs?

I answer to myself again. According to ARM documentation, the pointer to an unaligned struct must be explicitly defined as one using the keyword __packed, otherwise the "->" will just not work:

"When a pointer is declared as __packed, the compiler generates code that correctly accesses the dereferenced value of the pointer, regardless of its alignment. The generated code consists of a sequence of byte accesses, or variable alignment-dependent shifting and masking instructions, rather than a simple LDR instruction. Consequently, declaring a pointer as __packed incurs a performance and code size penalty."

https://developer.arm.com/documentation/dui0472/g/compiler-coding-practices/unaligned-pointers-in-c-and-c---code