malloc freezes my micro controller...

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I got a UC3A1256 and at some stage in my program I do a malloc and it seems to freeze my micro :(

I have print statements before and after and chased it to that malloc location. The print statement after the malloc will not show up on my hyperterminal!

I thought if memory was out, then malloc would return with NULL pointer rather than freezing the micro :|

Dont get it!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As usual, show code. E.g. the three lines (the prinrt, the malloc, and the print that follows) plus any definitions that these three lines use.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I create a task using this function:

Task *CreateTask(void *callback, unsigned long interval, unsigned char priority)
{
	Task *task = (Task *)malloc(sizeof(Task));
	if(task != NULL)
	{
		//fill task block here etc
		
		task->Next = NULL;
		task->Prev = NULL;	
	}
	return task;
}

After creating I add the task to a task que:

void AddTask(Task *task)
{
	if(TasksHead == NULL)
	{
		TasksHead = task;
		task->Prev = NULL;
	}
	else
	{
		TasksTail->Next = task;
		task->Prev = TasksTail;
	}
	TasksTail = task;
	task->Next  = NULL;
	NumberOfTasks++;	
}

Then later on once the task is no longer needed I remove it:

void RemoveTask(Task *task)
{
	if(task->Prev == NULL)
		TasksHead = task->Next;
	else
		task->Prev->Next = task->Next;

	if(task->Next == NULL)
		TasksTail = task->Prev;
	else
		task->Next->Prev = task->Prev;
	NumberOfTasks--;
	free(task);
}

After removal I at some stage again in the program Create and Add again...It is in the create malloc in the second time that I get a freeze. I had print statements before and just after the malloc to test it.

I fail to understand how memory limit could be an issue... as later on I dynamically allocate memories for sockets etc and free the momories as sockets are closed. This happens seemlessly...

I have tasks created and destroyed for services like KeepAliveService or NTP service...When a modem link is broken. I make sure all sockets are closed and memories freed and then do a dial session and then when PPP is up I call my LCP create service...it is in this LCP create task that the freeze occurs.

I have now decided to rather not remove the task but keep the task in an IDLE state and when the service is required (modem link is up) I just place the LCPkeep alive task to START state. This is ok. But would have been ideal if remove task and create (add) task worked fine :(

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

3 possiblities come to mind:

1) your printf() uses malloc(), so if you run out of memory in the malloc for the task structure, your subsequent debugging printf will be confused
2) some earlier code has corrupted malloc's data structures
3) malloc() is not reentrant, and somewhere in your code, you are calling malloc() in an preemptable context.

One thing to keep in mind: when using malloc, your memory could become fragmented after some usage; that might explain why the malloc might fail with insufficient memory the second time your LCP task is allocated.

- S

ps: doesn't this belong in an avr32 forum?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I assume you are suing freeRTOS, right? If so, you should use the portMalloc and portFree functions which are thread safe, instead of the "normal" versions of malloc and free.

Daniel Campora http://www.wipy.io

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mnehpets...erm... my print statement is a pure usart send string function...no memory alloc there.
I am thinking (2) is probly the most likely reason. Just cant find anything wrong so far with the code.. lol..
I am not sure I understand (3). Could you give an example?

danicampora...I am not using freeRTOS. This is standalone code..

Yes strictly speaking this could be a avr32 post but wondered if malloc freezing micro was a generic issue. I always thought if memory was not possible to be allocated malloc always returned with NULL rather than freezing the micro...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I am not sure I understand (3). Could you give an example?

Example: A home-grown RTOS is used. Somewhere in the code malloc() is called. During the execution of that, a timer interrupt occurs that switches the "process context". Now another process commences executing while the first is stalled in the middle of the malloc(). Finally the second process calls malloc(). If malloc() is not reentrant...

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mmmm... You have "tasks" in your code and still you say it is standalone, please give us some more info...
Are your tasks cooperative? or are your tasks preemptive and you are using your own custom scheduler/RTOS?

If your tasks are preemptive then you need to guard all malloc and free calls with a critical section, because as everyone has been telling, they are not re-entrant...
Maybe you are calling them from different interrupt routines? If there's the possibility of a malloc/free call being interrupted by another one, you need critical sections around 'em.

Daniel Campora http://www.wipy.io

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

They are cooperative tasks....just gets added in the task que and while loop (task scheduler) goes through every one of them and executes them once it finds a tick flag was set in a timer interrupt, after completion it then resets the tick flag. A very simple cooperative task scheduler.

Anyway this has really puzzled me...I have just for now stopped removing and adding tasks. Will just make the task dormant but changing its state rather than removing the task altogether.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
They are cooperative tasks....just gets added in the task que and while loop (task scheduler) goes through every one of them and executes them once it finds a tick flag was set in a timer interrupt, after completion it then resets the tick flag. A very simple cooperative task scheduler.

This probably won't solve the underlying issue, but you could change your CreateTask() code so that the caller passes a pointer to a Task structure. If you're lucky, the caller can use a static Task variable for this structure. This'll avoid the needed for malloc() and free() for this code.

- S

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes I use that method for other data structures in my code like say for example the sort of data I know will not be destroyed...for example struct Modem which holds some states and flags for the Modem interface. Such data is meant to exist for the whole duration of the program so I keep them as plain global structs rather than define as malloc pointers.

Meh I will investigate this later. For now as I say I am keeping my task dormant by manipulating its State to IDLE.