Search code examples
arrayscmemoryembeddedstm32

How does an array initialization causes hardfault error in STM32 Blue Pill?


I am working with STM32 Blue Pill(STM32F103C8T6) and using STM32CubeIDE-1.11.0, and implementing SPI and USB protocol. Here's my code block which induces the error:

#define Read_Size 6743

static uint32_t Flash_Address = 0x08000000;

int main(void)
{

    uint8_t Read_Buffer[Read_Size];         //Instance 1 of using Read_Size
    uint8_t spi_Rxdata[Read_Size] = {0};    //Instance 2 of using Read_Size
    while(1){
       if(Flash_Data_Transmission_Flag == 1){
      while(Flash_Address != 0x08100000){
              HAL_Delay(100);
              for(uint16_t j=0; j<**Read_Size**; j++){          //Instance 3 of using Read_Size
             Read_Buffer[j] = *(__IO uint8_t *)Flash_Address;
             Flash_Address++;
          }
          Flash_Address++;
              CDC_Transmit_FS(Read_Buffer, sizeof(Read_Buffer));
           }
        }
     }
    
}

There are only 3 instances of Read_Size If I change the value of Read_size to more than 6743, code goes into HardFault_Handler() . (I found 6743 by trial). I understand that a uint8_t array will have size n-bytes, when there are n-values in it, so I am doubtful if it has anything to do with the segmentation fault as the memory should not be exceeding if I define Read_Size as 8192.

Here are my code's section headers for referencing to the memory usage: enter image description here

As Shown in STM32CubeIDE after code compilation: enter image description here

Ram is around 11KB unused, which can be used to store uninitialized array in the stack.

minimum Heap and Stack memory size defined in the linker script

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

May I please know what I am doing wrong, and how to tackle this array initialization problem to prevent the system going into hardfault error?


Solution

  • You have around 11 kB of free RAM and try to use 13 kB. So the hard answer is that you either need to choose a MCU with more RAM or use less RAM.

    You can have the compiler/linker help detect problems like this. In this case, the required stack size is set at 0x800 bytes (2 kB) which is clearly not enough to accommodate the two arrays of around 6.5 kB. Hence, in this case, the required stack size would need to be maybe 0x4000 bytes (16 kB) assuming there are no other large variables allocated on the stack.

    However, since it is difficult to assess the required stack size reliably, it is normally a better strategy to leave the required stack size "small" (e.g. 0x800) and never allocate variables of significant size on the stack. Instead, make them static:

        static uint8_t Read_Buffer[Read_Size];
        static uint8_t spi_Rxdata[Read_Size] = {0};
    

    This will allow the linker to take such variables into account when determining if the memory use of the program fits with the available amount of RAM and raise an error if that is not the case.