SuicidalTasks Kills Cortex R4F Port

westmorelandeng wrote on Friday, March 20, 2015:

Hello All,

I ran vCreateSuicidalTasks() in a new port - it ran until memory ran out on the port.

uxTasksRunningAtStart: 36

When vApplicationMallocFailedHook was called -
looks like the CREATOR task was running;
uxCurrentNumberofTask: 208. I am using heap5.c for this port.

What would prevent it from killing off the tasks as it should during runtime?

Thanks,
John W.

rtel wrote on Friday, March 20, 2015:

The memory is actually returned to the heap by the idle task - is your application letting the idle task run? Or is the idle task starved out?

Regards.

westmorelandeng wrote on Friday, March 20, 2015:

Well, that’s an interesting question. It would appear that the task creation eventually does starve the IDLE task until it doesn’t get a chance to run. My debugger gets a little unstable when this happens or I’d be able to know for sure - but I would have to take an educated guess that is what is happening. Sort of like a race condition or speed path of sorts.

Regards,
John

westmorelandeng wrote on Friday, March 20, 2015:

I cut down the app so that the IDLE task, one timer task, and the Suicidal Tasks are running and it still happens. The IDLE task (hook) is running. # of tasks still large when the port dies.

westmorelandeng wrote on Friday, March 20, 2015:

Is there something the IDLE task hook should be doing?

rtel wrote on Friday, March 20, 2015:

No - the hook doesn’t have to even be defined.

Regards.

westmorelandeng wrote on Friday, March 20, 2015:

So, if the IDLE task is running; I have verified that, what could be causing the Suicidal Tasks from being killed? It appears that the tasks aren’t killing each other - I think that needs to occur before the memory can be reclaimed.

INCLUDE_vTaskDelete is set to 1.

uxNumberOfTasks ~ 210 when the malloc fails. Is that a real # or does that really mean the max number of tasks that have been created?

in death.c - this is being run:

if( xTaskToKill != NULL )
	{
		/* Make sure the other task has a go before we delete it. */
		vTaskDelay( ( TickType_t ) 0 );

		/* Kill the other task that was created by vCreateTasks(). */
		vTaskDelete( xTaskToKill );

		/* Kill ourselves. */
		vTaskDelete( NULL );

}

rtel wrote on Friday, March 20, 2015:

No idea I’m afraid. Which heap_n.c are you using?

westmorelandeng wrote on Friday, March 20, 2015:

From OP - I am using heap5.c for this port.

westmorelandeng wrote on Friday, March 20, 2015:

But, I only defined one heap region.

HeapRegion_t xHeapRegions[] =
{
{ ( uint8_t * ) 0x08020000UL, 0x1FF00 }, // << Defines a block of 0x10000 bytes starting at address 0x80000000
// { ( uint8_t * ) 0x90000000UL, 0xa0000 }, // << Defines a block of 0xa0000 bytes starting at address of 0x90000000
{ NULL, 0 } // << Terminates the array.
};

vPortDefineHeapRegions( xHeapRegions ); /* << Pass the array into vPortDefineHeapRegions(). */

westmorelandeng wrote on Tuesday, March 24, 2015:

Hello Richard,

I took the CCS port that is part of the distribution; changed heap4 to heap5.c - and the
suicidal tasks have the same affect as when running under IAR. I have some screen shots attached.

…heap5.jpg is beginning
…heap5_d.jpg is just prior to MallocFailedHook being called.

Regards,
John

westmorelandeng wrote on Tuesday, March 24, 2015:

And, for something completely different - when I define all of these to run:

vStartIntegerMathTasks( tskIDLE_PRIORITY );                
vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );        
vCreateBlockTimeTasks();
vStartCountingSemaphoreTasks();
vStartGenericQueueTasks( tskIDLE_PRIORITY );
vStartRecursiveMutexTasks(); 
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );        
    vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); 
vStartMathTasks( mainFLOP_TASK_PRIORITY );        
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );    
    
/* Create the register test tasks, as described at the top of this file. */
xTaskCreate( vRegTestTask1, "Reg1...", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );    
xTaskCreate( vRegTestTask2, "Reg2...", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );   

/* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */
xTimer1 = xTimerCreate( "CheckTimer",					/* A text name, purely to help debugging. */
						( mainCHECK_TIMER_PERIOD_MS ),	/* The timer period, in this case 3000ms (3s). */
						pdTRUE,							/* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
						( void * ) 0,					/* The ID is not used, so can be set to anything. */
						prvCheckTimerCallback			/* The callback function that inspects the status of all the other tasks. */
					 );

if( xTimer1 != NULL )
{
	xTimerStart( xTimer1, mainDONT_BLOCK );
}

/* Create the software timer that performs the 'LED spin' functionality,
as described at the top of this file. */
xTimer2 = xTimerCreate( "LEDTimer",					/* A text name, purely to help debugging. */
						( mainLED_TIMER_PERIOD_MS ),/* The timer period, in this case 75ms. */
						pdTRUE,						/* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
						( void * ) 0,				/* The ID is not used, so can be set to anything. */
						prvLEDTimerCallback			/* The callback function that toggles the white LEDs. */
					 );

if( xTimer2 != NULL )
{
	xTimerStart( xTimer2, mainDONT_BLOCK );
}

/* The set of tasks created by the following function call have to be
created last as they keep account of the number of tasks they expect to see
running. */

// vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );

	vTaskStartScheduler();
             for ( ;; );

The IDLE (hook) task runs! Hmmm.

westmorelandeng wrote on Thursday, March 26, 2015:

Hello Richard,

Is this a bug with heap5.c?

Thanks,
John

rtel wrote on Thursday, March 26, 2015:

Is this a bug with heap5.c?

I would never say “no”, but I would say it is extremely unlikely.

Regards.

westmorelandeng wrote on Thursday, March 26, 2015:

Richard,

OK - as the above shows, I added to a demo that is with the distribution and when running Suicidal Tasks; it will fail. I changed heap4.c to heap5.c.

All things equal (I pretty much ran the demo as is) - what is wrong?

Regards,
John

rtel wrote on Thursday, March 26, 2015:

Are you aware that heap_5 must be initialised before it is used? Can
you post the code used to initialise it.

Regards.

westmorelandeng wrote on Thursday, March 26, 2015:

Please look at what I have posted in this thread - 10th post?

Thanks,
John
// repost:
But, I only defined one heap region.
HeapRegion_t xHeapRegions[] =
{
{ ( uint8_t * ) 0x08020000UL, 0x1FF00 }, // << Defines a block of 0x10000 bytes starting at address 0x80000000
// { ( uint8_t * ) 0x90000000UL, 0xa0000 }, // << Defines a block of 0xa0000 bytes starting at address of 0x90000000
{ NULL, 0 } // << Terminates the array.
};
vPortDefineHeapRegions( xHeapRegions ); / << Pass the array into vPortDefineHeapRegions(). /

rtel wrote on Thursday, March 26, 2015:

So the line:

{ ( uint8_t * ) 0x08020000UL, 0x1FF00 }

Shows the heap being at address 0x08020000 - is the linker also placing
variables at that address?

If you are sharing a block of RAM with the linker best to define like this:

static uint8_t ucMyHeap[ 0x1ff00 ];

{ ucMyHeap, sizeof( ucMyHeap ) }

then the linker will place the memory for you.

Regards.

westmorelandeng wrote on Thursday, March 26, 2015:

No. I have a separate linker control file. The two memory regions do not intersect.

rtel wrote on Thursday, March 26, 2015:

I’m afraid that without being able to sit down with the project I’m not
sure what to suggest - especially as the HalCoGen code is not the same
as the version in the FreeRTOS distribution. What is the part number of
the chip you are using?