Finding configTOTAL_HEAP_SIZE Maximum Value

spflanze wrote on Tuesday, March 15, 2016:

The -O1 optimization produces this assembly code:

                    StartThreadUART_Rx:
08002098:  StartThreadUART_Rx+0   push {r4, r5, r6, lr}
0800209a:  StartThreadUART_Rx+2   sub sp, #16
0800209c:  StartThreadUART_Rx+4   sub.w r3, sp, #12224    ; 0x2fc0
080020a0:  StartThreadUART_Rx+8   movs r2, #0
080020a2:  ...tThreadUART_Rx+10   str.w r2, [r3, #-60]
159                               { xQueueReceiveResult = xQueueReceive( QueueUART_RxHandle, (void *)&rxchar, portMAX_DELAY );
080020a6:  ...tThreadUART_Rx+14   ldr r5, [pc, #128]      ; (0x8002128 <StartThreadUART_Rx+144>)
161                                   HAL_UART_DMAResumeStat = HAL_UART_DMAResume( &huart2 );
080020a8:  ...tThreadUART_Rx+16   ldr r6, [pc, #128]      ; (0x800212c <StartThreadUART_Rx+148>)
159                               { xQueueReceiveResult = xQueueReceive( QueueUART_RxHandle, (void *)&rxchar, portMAX_DELAY );
080020aa:  ...tThreadUART_Rx+18   movs r3, #0
080020ac:  ...tThreadUART_Rx+20   mov.w r2, #4294967295
080020b0:  ...tThreadUART_Rx+24   add.w r1, sp, #15
080020b4:  ...tThreadUART_Rx+28   ldr r0, [r5, #0]
080020b6:  ...tThreadUART_Rx+30   bl 0x8006984 <xQueueGenericReceive>

The Bus Fault happens just as before at …Rx+10.

Is it possible this is a GCC bug?

spflanze wrote on Tuesday, March 15, 2016:

I commented out code in void StartThreadUART_Rx() so that this was all that was left in effect:

void StartThreadUART_Rx(void const * argument)
{ for(;;){}
}

The instructions that caused the Bus Fault were not produced, and the thread ran normally.

I then brought back only the call to xQueueReceive() such that the code in effect was:

void StartThreadUART_Rx(void const * argument)
{ uint8_t rxchar;
    BaseType_t xQueueReceiveResult;
    for(;;)
    { xQueueReceiveResult = xQueueReceive( QueueUART_RxHandle, (void *)&rxchar, 10000 ), portMAX_DELAY );
    }
}

The assembly code that caused the Bus Fault returned.

Next I tried:

void StartThreadUART_Rx(void const * argument)
{ size_t len 
   for(;;)
   { len = strlen("test");
   }
}

The assembly code that caused the Bus Fault was not present. This ran normally.

Next I tried:

void StartThreadUART_Rx(void const * argument)
{ HAL_StatusTypeDef HAL_UART_DMAResumeStat; 
   for(;;)
   { HAL_UART_DMAResumeStat = HAL_UART_DMAResume( &huart2 );
   }
}

The Bus Fault causing assembly code returned.

There are certain function calls the cause the Bus Fault assembly code to be created.

rtel wrote on Wednesday, March 16, 2016:

0800209c: StartThreadUART_Rx+4 sub.w r3, sp, #12224 ;

So this line is still weird. Then there are these lines:

080020a0: StartThreadUART_Rx+8 movs r2, #0
080020a2: …tThreadUART_Rx+10 str.w r2, [r3, #-60]

So it looks like it is loading a base address from into r3, maybe the
base of a structure or array, but using an address which is off memory.
Then it is indexing into an offset from that base address.

I commented out code in void StartThreadUART_Rx() so that this was all
that was left in effect:

void StartThreadUART_Rx(void const * argument)
{ for(;;){}
}

The instructions that caused the Bus Fault were not produced, and the
thread ran normally.

I then brought back only the call to xQueueReceive() such that the code
in effect was:

void StartThreadUART_Rx(void const * argument)
{ uint8_t rxchar;
BaseType_t xQueueReceiveResult;
for(;:wink:
{ xQueueReceiveResult = xQueueReceive( QueueUART_RxHandle, (void *)&rxchar, 10000 ), portMAX_DELAY );
}
}

The assembly code that caused the Bus Fault returned.

Even if QueueUART_RxHandle was not a valid handle it would not explain
the asm code.

I think you have one too many ‘)’ brackets in your line to
xQueueReceive, but assume that is a typeo in adding the code to the
forum post.

Next I tried:

void StartThreadUART_Rx(void const * argument)
{ size_t len
for(;:wink:
{ len = strlen(“test”);
}
}

The assembly code that caused the Bus Fault was not present. This ran
normally.

Ok.

Next I tried:

void StartThreadUART_Rx(void const * argument)
{ HAL_StatusTypeDef HAL_UART_DMAResumeStat;
for(;:wink:
{ HAL_UART_DMAResumeStat = HAL_UART_DMAResume( &huart2 );
}
}

The Bus Fault causing assembly code returned.

There are certain function calls the cause the Bus Fault assembly code
to be created.

So this shows it is not related to the xQueueReceive() function, or how
it is used. Very very strange!

spflanze wrote on Wednesday, March 16, 2016:

This appears to me to be a compiler bug. As a work around I am going to try to do the function calls in assembly code. I am studying this document:
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf
to learn how to do this. If you can recommend any other I would appreciate your doing so.

The above xQueueReceive() call arguments were in error. It was a remnant of an experiment to find out if less than the maximum delay would make a difference here. It should have been:
xQueueReceive( QueueUART_RxHandle, (void *)&rxchar, portMAX_DELAY );

spflanze wrote on Thursday, March 17, 2016:

An examination of the disassembly code showed that strlen() is not actually called. It was instead placed inline. And the compiler was smart enough to count the number of characters in the string, so not even counting characters is done in the instructions it produced. Instead it simply set len to 4.

So I tried the function malloc() in its place, and the instructions that produce the Bus Fault appeared. It appears that any function call in the body of StartThreadUART_Rx() causes those Bus Fault instructions to be created, not just FREERTOS ones.

spflanze wrote on Thursday, March 17, 2016:

This problem is solved. It became apparant this is a compiler issue and not a FREERTOS issue. So I created this thread at GCC where I got the answer:
http://gcc.1065356.n5.nabble.com/Bus-Fault-td1246632.html#a1246958

The problem was the -fstack-check compiler option. When this was removed the code that caused the Bus Fault was no longer created.

I thank you for your help :slight_smile:

rtel wrote on Friday, March 18, 2016:

I thank you for your help :slight_smile:

…and thanks for taking the time to report back.

fedeandrades wrote on Monday, May 30, 2016:

where the option to disable the “-fstack-check” in the STM32 workbenck of AC6, I have the same problem and if this solves it would be wonderful to know how.

regreted, written in English by web translator

thanks.

edit:
MCF GCC Compiler All options:
-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -D__weak=“attribute((weak))” -D__packed=“attribute((packed))” -DUSE_HAL_DRIVER -DSTM32F429xx -I…/Inc -I"L:\DESIGN\CPUARM\WORKSPACE.SOFT\RTOS2016_V1\Src\minini_12b" -I…/Drivers/STM32F4xx_HAL_Driver/Inc -I…/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy -I…/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I…/Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I…/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc -I…/Middlewares/Third_Party/FatFs/src -I…/Middlewares/Third_Party/FreeRTOS/Source/include -I…/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS -I…/Drivers/CMSIS/Include -I…/Drivers/CMSIS/Device/ST/STM32F4xx/Include -O0 -g3 -Wall -fmessage-length=0 -ffunction-sections -c -fmessage-length=0

i not have -fstack-check !!! but the problem still occurs

heinbali01 wrote on Tuesday, May 31, 2016:

Frederico,

Lo siento, aunque el Español es mucho mas bonito que el Ingles :-), tu tendrás que aprender mucho Ingles si tu quieres volverte en un buen programador de embedded software. No es suficiente utilizar el Google Translate.

Porque piensas que tu tienes el mismo problema que la persona “Artist”? Qué estas observando? Que hace tu programa?

I’m sorry, although Spanish is much more beautiful than English :-), you will have to master English if you want to become a good embedded software programmer. It is not enough to use Google Translate.

Why do you think that you have a similar problem as the poster “Artist”, here above? What do you observe? What does the program do?