about malloc buffer in interrupt ISR

labelsr wrote on Sunday, April 13, 2014:

Can I call pvPortMalloc()(heap2.c,FreeRTOS 8.0) in the interrupt handler(LPC17XX platform)?
In my platform, I recv data in the USB ISR, and when I recv some data, I want to malloc buffer and copy rx data to it. I am not sure whether I can call pvPortMalloc() in the INT ISR. Can anybody tell me can I? Or can anybody tell me how to handle USB RX data in the USB INT handler?

davedoors wrote on Sunday, April 13, 2014:

It is never a good idea to call malloc in an ISR, whether the program is using FreeRTOS or not.

labelsr wrote on Sunday, April 13, 2014:

Yes, it is true that malloc buffer in INT ISR is not a good idea. But I really need to alloc buffer in the ISR INT. For example, I print log in the USB ISR, I malloc some buffer first,copy LOG to the malloced buffer and post this buffer pt to the LOG task. If malloc is not permitted, what should I do?
Can I portDISABLE_INTERRUPTS() before malloc() and portENABLE_INTERRUPTS() after malloc()?

richard_damon wrote on Sunday, April 13, 2014:

If you really need to use malloc/free in interrupts, then you need to bracket all calls to them in something that keep you from reentering it. This could be a portDISABLE_INTERRUPTS() outside of interrupt routines.

A better solution, especially if your ISR just needs to free a buffer, is to create a queue that holds void* pointers, and have the ISR queue up the pointer, then a high priority task waits on the queue and frees it.

Even better could be to set up a pool of buffers that your application acquires one to fill, pass it around, and when done it is put back in the pool. This does require that you analysis your usage to set up the sizes of the pools.

The BIG problem with applications that use malloc/free in operation is that you really do need to test EVERY malloc call for failure and handle it in a reasonable manner, and this code is very hard to test as part of a full system. (malloc in startup is much more consistent, and thus testable)

rtel wrote on Sunday, April 13, 2014:

You are going to have problems using the heap_n.c files that come with FreeRTOS as they (at least the one I just looked at) only suspend the scheduler when allocating memory - they don’t disable interrupts. Therefore you could get data corruption if a task and interrupt call malloc at the same time. You could write your own versions that disable interrupt instead of just disabling the scheduler, but if you get away with that or not will actually depend on the port you are using and the priority of the interrupt.

Better to use something like the mechanism described on the following page - make the priority of the timer task the highest priority in your system to ensure the pended function executed immediately that the interrupt has completed.


labelsr wrote on Tuesday, April 15, 2014:

Thank you for your reply.
I migrate mem-pool code to my platform,it is high-efficience. So I think disable INT before POOL_ALLOC() and re-enable INT after POOL_ALLOC() is OK in the ISR. In my opinion, if MALLOC is in ISR, I need to disable INT before MALLOC and re-enable INT after it. If it is in task, I need to suspend scheduler before it and resume scheduler after it. Am I right?

richard_damon wrote on Tuesday, April 15, 2014:

If you use malloc in an ISR, then ALL calls to malloc and free need to be bracketed by the equivalent of disable interrupt/enable interrupt. In the ISR itself you may need something a bit different, as you don’t want to totally reenable interrupts until the ISR is done.