cancel
Showing results for 
Search instead for 
Did you mean: 

Static Constant Variable Allocated as RAM when used by HAL I2C functions STM32CubeIDE

EPala.2
Associate III

Hi, I am working on a project where I have a 4096 byte data array that I will be passing to another component via I2C. This array is a constant, so I declared it as follows in order to have it live in flash memory rather than RAM:

static const uint8_t myArray[4096] = {
0x80,0x40,0x00,0x11,
...

However, when I pass a pointer to this variable to the HAL I2C functions, it suddenly gets placed in RAM and I get a RAM overflow error from the compiler:

HAL_I2C_Slave_Sequential_Transmit_IT(&h_i2c, (uint8_t *)myArray, 4096, I2C_FIRST_AND_LAST_FRAME);
/Applications/STM32CubeIDE.app/Contents/Eclipse/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.macos64_1.0.0.202111181127/tools/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: my-proj.elf section `._user_heap_stack' will not fit in region `RAM'
/Applications/STM32CubeIDE.app/Contents/Eclipse/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.macos64_1.0.0.202111181127/tools/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: region `RAM' overflowed by 16 bytes
collect2: error: ld returned 1 exit status
make: *** [makefile:87: stereo-slo-051.elf] Error 1
"make -j11 all" terminated with exit code 2. Build might be incomplete.

Any idea what's going on here and how I can fix it?

8 REPLIES 8
Bob S
Principal

I can't replicate that, and I strongly suspect something else is going on. Look at the map file. And post actual code and which processor you are targeting.

EPala.2
Associate III

What should I be looking for in the map file? I did look in there earlier, and could see that the static const array was going into RAM but not much else.

The processor we are targeting is the STM32L051C8TR

For sharing code, a lot of this is proprietary so we're not trying to post it publicly, hence the snippet, it's also a large project with a lot of header files so not something I can just copy and paste. What do you think are the relevant sections you'd need to diagnose the problem and what would be the best way to share those?

S.Ma
Principal

I guess you tried to remove the "static" and rebuild ? Just in case.

Change your array name to find out if it changes anything.

Your toolchain configuration or the linker memory mapping definition file may have something wrong in it.

KnarfB
Principal III

Cannot reproduce. Even if I do

  for(int i=0; i<sizeof(myArray); ++i)
	  putchar(myArray[i]);
 
  HAL_I2C_Slave_Sequential_Transmit_IT(&hi2c1, (uint8_t *)myArray, 4096, I2C_FIRST_AND_LAST_FRAME);
 
  HAL_UART_Transmit(&huart3, (uint8_t*)myArray, strlen(myArray), 1000);

The Build Analyzer shows that the array sits in .rodata in the flash.

If everything else fails, you may declare a separate section in the .ld file and place an attribute to the array like

static const uint8_t myArray[4096] __attribute__ ((section ("mySection"))) = {0x80,0x40,0x00,0x11 };

hth

KnarfB

Is this variable declared inside or outside a function?

Show command line with which you (your Eclipse) run the compiler.

Do you use some modified linker script?

The real thing would be to prepare a minimal but complete compilable example which exhibits the problem for others to reproduce. But tell us those things I asked above first.

JW

EPala.2
Associate III

Hi, after further testing I don't think this actually has anything to do with the array, but rather with some kind of error in the I2C library code:

I ran the following test:

static struct {
	I2C_HandleTypeDef * h_i2c;
	uint8_t rx_vals[16];
 
	// Pointer to memory image of EEPROM
	uint8_t * rom_image;
	uint32_t rom_size;
 
	// Current index into memory image (starting at zero)
	uint16_t cur_addr;
 
} emu_state;
 
/**
 * @brief Initializes
 * Note: The I2C port needs to be configured / initialized properly in CubeMX including
 *       the I2C slave address
 * @param i2ch Pointer to I2C peripheral handle
 * @param rom_image Pointer to ROM image
 * @param rom_size ROM image size in bytes
 */
void 	emu_24aa32a_init( I2C_HandleTypeDef * i2ch, const uint8_t * rom_image, uint32_t rom_size ) {
	assert(i2ch);
	assert(rom_image);
	assert(rom_size);
 
	emu_state.h_i2c = i2ch;
 
	emu_state.rom_image = (uint8_t *)rom_image;
	emu_state.rom_size = rom_size;
 
	emu_state.cur_addr = 0;
 
//	HAL_I2C_Slave_Sequential_Receive_IT(emu_state.h_i2c, emu_state.rx_vals, 2, I2C_FIRST_FRAME);
}
//in main:
emu_24aa32a_init( &hi2c1, VerbHex, 4096 );
// array declaration:
static const uint8_t VerbHex[4096] = {
0x80,0x40,0x00,0x11,
0x01,0x90,0x02,0x92, ...

And it compiles fine. But when I uncomment the I2C library function to queue the receive, I get a memory overflow error (note that this library function does not even touch the large array):

HAL_I2C_Slave_Sequential_Receive_IT(emu_state.h_i2c, emu_state.rx_vals, 2, I2C_FIRST_FRAME);
12:46:43 **** Incremental Build of configuration Debug for project my-proj ****
make -j11 all 
arm-none-eabi-gcc "/{project-path}/spin-src/drivers/driver-24AA32A-emulation.c" -mcpu=cortex-m0plus -std=gnu11 -g3 -DDEBUG -DMOD_LOOKUP_SIZE=128 -DUSE_HAL_DRIVER -DSTM32L051xx -DSTEREO_SLO -c -I../Core/Inc -I"/{project-path}/spin-src/drivers" -I"/{project-path}/spin-src/system" -I"/{project-path}/spin-src/ui" -I"/{project-path}/spin-src" -I../Drivers/CMSIS/Include -I../Drivers/STM32L0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Device/ST/STM32L0xx/Include -I../Drivers/STM32L0xx_HAL_Driver/Inc/Legacy -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/spin-src/drivers/driver-24AA32A-emulation.d" -MT"Core/spin-src/drivers/driver-24AA32A-emulation.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/spin-src/drivers/driver-24AA32A-emulation.o"
arm-none-eabi-g++ -o "my-proj.elf" @"objects.list"   -mcpu=cortex-m0plus -T"/{project-path}/my-proj/STM32L051C8TX_FLASH.ld" --specs=nosys.specs -Wl,-Map="my-proj.map" -Wl,--gc-sections -static --specs=nano.specs -mfloat-abi=soft -mthumb -Wl,--start-group -lc -lm -lstdc++ -lsupc++ -Wl,--end-group
/Applications/STM32CubeIDE.app/Contents/Eclipse/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.macos64_1.0.0.202111181127/tools/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: my-proj.elf section `._user_heap_stack' will not fit in region `RAM'
/Applications/STM32CubeIDE.app/Contents/Eclipse/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.macos64_1.0.0.202111181127/tools/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: region `RAM' overflowed by 16 bytes
collect2: error: ld returned 1 exit status
make: *** [makefile:87: my-proj.elf] Error 1
"make -j11 all" terminated with exit code 2. Build might be incomplete.
 
12:46:44 Build Failed. 3 errors, 0 warnings. (took 704ms)

Does this point to anything?

Any RAM will overflow at some point. Compare the memory usage with and without that last function call. Use the Build Analyzer view Memory Regions/Details. What are the differences?

KnarfB

Pavel A.
Evangelist III

Decrease your heap size by 16 bytes. Or 20.