FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [December 2016 Threads]
I'm facing an error within vSemaphoreCreateBinary(..). The macro looks like this:
~~~
define vSemaphoreCreateBinary( xSemaphore ){
( xSemaphore ) = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
if( ( xSemaphore ) != NULL ) \
{ \
xSemaphoreGive( ( xSemaphore ) ); \
} \
}
~~~
The application runs into a hardfault within xSemaphoreGive(). xSemaphore, which is a pointer, is pointing to the address 0xc18f04f. This is not a valid address and accessing it leads to a hardfault.
I used the debugger to step through xQueueCreate() line by line but wasn't able to detect sth abnormally.
Here is a screenshot which shows that the pointer pxNewQueue points to address 0x20001130. This is a valid address.
I do not understand why the address changes to 0xc18f04f? Any hint is highly appreciated.
I'm using FreeRTOS V6.1.1 with Atollic TrueSTUDIO 7.0.1 on a STM32F205.
I was able to reproduce the same behaviour in an other project where FreeRTOS isn't used at all. The issue is not related to FreeRTOS.
I spent another day looking at this issue. The issue is caused by a collision of heap and stack. TrueSTUDIO comes with two options: Dynamic heap size (default) and Fixed heap size. In projects where no RTOS is used Atollic recommends to use the dynamic option. This worked fine and I was able to solve above issue by this change for projects where FreeRTOS is not used.
However, for projects with FreeRTOS a dynamic heap size doesn't seem to be an option. Out of the user guide:
> If using an RTOS, it is recommended to generate a system calls file, and select
the Fixed Heap size option. This option requires that the MinHeapSize
symbol is defined in the linker script .ld file. The .ld file is stored in the root
directory of the currently selected project. The heap size defined by
_MinHeap_Size must meet the heap size required by the application.
The IDE automatically created a linker and a syscalls file. For the linker file it makes no difference whether dynamic or fix heap size has been selected - it looks the same in both cases. Here the interessting lines of the linker script:
~~~
/* Highest address of the user mode stack /
_estack = 0x2001c000; / end of 112K RAM */
/* Generate a link error if heap and stack don't fit into RAM /
MinHeap_Size = 0; / required amount of heap /
MinStack_Size = 0x400; / required amount of stack */
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 768K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 112K
MEMORYB1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
}
~~~
Heap size is 0 and stack size is 1K. **Is it somehow possible to calculate those values before building the application? Shall the minimal heap size be equal to the FreeRTOS config value configTOTALHEAP_SIZE?**
The second auto generated file is the syscalls file. This file changes completely when you compare projects with dynamic heap size and fix heap size. I think the central part of this file is the implementation of the function sbrk(int32t incr):
~~~
caddrt _sbrk(int32t incr)
{
extern uint32t _MinHeapSize; /* _MinHeapSize symbol defined in the linker script. */
extern uint8t end asm("end");
const uint8t *maxheap = (uint8t*)((uint32t)&end + (uint32t)&MinHeapSize);
static uint8t *heapend;
uint8t *prevheap_end;
if (heapend == 0)
heapend = &end;
prevheapend = heapend;
if (heapend + incr > maxheap)
{
// write(1, "Heap and stack collisionn", 25);
// abort();
errno = ENOMEM;
return (caddrt) -1;
}
heap_end += incr;
return (caddrt) prevheapend;
}
~~~
The collision detection fails obviously as _MinHeap_Size is 0. Unfortunately the application does not abort at this point but continues to run. The consequence was in my case that the pointer of a queue was overridden and invalid. I would prefer to enter an endless loop if application runs out of heap. What do you think - does this make sense? Does the function itself make sense when used with FreeRTOS??
Thanks in advance for any help.
The function looks like it would make sense (but maybe not with MinHeapSize == 0) to provide a seperate malloc heap. It should return -1 to signal that there isn't more memory, and maybe the heap functions can't handle that on the initial allocation. The proper value of Min Heap will depend on how much heap memory is needed from this heap.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.