Heap strange behaviour on ATMEGA128, AVR-GCC

baiangel wrote on Sunday, May 14, 2006:

Hi everyone!

I am using the AVR-GCC port of FREE-RTOS on ATMEGA128 with 32k external memory. I have set my heap size the follwoing way:
#define configTOTAL_HEAP_SIZE        ( (size_t ) ( 10000 ) )

Then I have the following definitions and initializations:

    xTaskCreate( Connect, "Connect", 200, NULL, CONNECT_ETHERNET_TASK_PRIORITY, NULL );
    xTaskCreate( I_O, "I/O", 100, NULL, I_O_TASK_PRIORITY, NULL );
    xTaskCreate( FIM1, "FP1", 300, NULL, FINGERPRINT1_TASK_PRIORITY, NULL );
    xTaskCreate( FIM3, "FP3", 300, NULL, FINGERPRINT3_TASK_PRIORITY, NULL );
    xTaskCreate( Controller, "CONTROL", 300, NULL, CONTROLLER_TASK_PRIORITY, NULL );
    xTaskCreate( CheckAlive, "CHECK", 100, NULL, CHECKALIVE_TASK_PRIORITY, NULL );
    xTaskCreate(Task_Report_Busy, "Busy", 100, NULL, REPORT_BUSY_PRIORITY, NULL);  
Queue_Busy_Tasks = xQueueCreate(10, 1);
    vSemaphoreCreateBinary(Controller_Node_Semaphore); 
vSemaphoreCreateBinary( FIM1_Node_Semaphore);            vSemaphoreCreateBinary( FIM3_Node_Semaphore);            vSemaphoreCreateBinary( Server_Alive_Semaphore);    
vSemaphoreCreateBinary( FIM1_Receive_Semaphore );   
vSemaphoreCreateBinary( FIM3_Receive_Semaphore );    

    vSemaphoreCreateBinary(Sem_Controller_Ready);        
    vSemaphoreCreateBinary(Sem_FIM1_Ready);
    vSemaphoreCreateBinary(Sem_FIM2_Ready);
    vSemaphoreCreateBinary(Sem_FIM3_Ready);
    vSemaphoreCreateBinary(Sem_FIM4_Ready);
   
    vSemaphoreCreateBinary( Output4_Semaphore );
    vSemaphoreCreateBinary( Output5_Semaphore );

After startig the scheduler, everything works just fine. But, when I increase the stack size of the tasks to let say 700 bytes each, the program crashes. Even when increasing the heap size to 20k (!!!), the  program still crashes. The initialisation is correct to Sem_FIM3_Busy, after which the MCU restarts itself. The exatct function, where this happens is "vListInitialise( &( pxNewQueue->xTasksWaitingToReceive))", whcich is being called from "xQueueCreate";Is there any known issue in the RTOS or it is my mistake? I have checked the source 3 or 4 times and I still cannot see any memory overlapping problem or something similar. I would appreciate any oppinion. Tahnk you in advance!

jwestmoreland wrote on Monday, May 15, 2006:

Hello,

Why do you want to increase stack size to 700 bytes per task?  Seems like a lot to me for an embedded system.  That’s a lot of arguments per task to be pushed on the stack.

Do you have 20K of RAM on this processor?

xQueueCreate() fails (probably) because there’s no memory left.

You can write a quick test by just doing successive pvPortMalloc()'s and see when you fail - that’ll tell you what FreeRTOS thinks its memory size is (add up bytes per pvPortMalloc until you get a failure).

HTH,
John W.

baiangel wrote on Monday, May 15, 2006:

John, thank you for the advice. I have done what you suggested. After configuring the heap size to 15000 bytes, the RTOS allocates 7499 blocks of size 2 bytes, or 21 blocks of size 700. So I guess the size of the allocated block is not a problem. The only problem I saw, was that the size of the block actually matters when using heap_2.c. The RTOS was hardly able to allocate 2310 bytes.

P.S.
I have а large set of local (for the tasks) variables. That is why I need so much space

nobody wrote on Thursday, May 18, 2006:

Your problem is that the ATMEGA128 only has 4K RAM!

You have 128K Flash, Not Ram

baiangel wrote on Saturday, May 20, 2006:

I am using the AVR-GCC port of FREE-RTOS on ATMEGA128 with 32k external memory

jwestmoreland wrote on Sunday, May 21, 2006:

Angel,

Since you’re using external memory - have you fixed this up so your system (FreeRTOS) knows it has 32K of dynamic memory available? (+4K internal)

Since you said that FreeRTOS was hardly able to allocate 2310 bytes - that makes me think it only ‘knows’ about the internal 4K of RAM that’s on-chip.

Please note - (I think) heap_2.c assumes contiguous memory - you may have to do some coding   to fix this if you have RAM locations that are non-contiguous.  You may be able to fix this up in your linker command file by defining a segment to include all of the available RAM.  This is probably preferred - to let the linker tools fix this up for you vs. changing any of the code. 

If your toolset has it’s own malloc and free - you may try linking in heap_3.c - see if it works - and then go back to using heap_2.c.  If heap_3.c works - that means the linker has fixed up the segments.  So take a look at the linker map file or whatever the AtMel tools calls it to see how it mapped the the RAM so FreeRTOS (or more importantly - the malloc and free functions of the tools) knew where to put dynamic memory.

HTH,
John W.