This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to solve A_invBlockFreed when freeing message on DSP

Hi experts,

Got into a new one recently.

Here is my setup:

DM8168 z3

ARM                          DSP

Queue                       Queue 

HeapInstance            HeapInstance

------------Shared heap-----------------

EZSDK: ezsdk-5_05_01_04

When the ARM knows the DSP queue has been created it opens it, same the other way.

Then ARM & DSP apps do the following,

ARM: MessageQ_alloc : ok

ARM: MessageQ_put : ok

DSP: MessageQ_get: ok

DSP: MessageQ_free: error

This it the error I am getting

N:DSP P:0 #:00004 M:ti.sdo.ipc.heaps.HeapBufMP S:ERROR: line 672: assertion failure: A_invBlockFreed: Invalid block being freed
MessageQ_alloc

The assertion failure details are here, HeapBufMP.c Line 672:

Void ti_sdo_ipc_heaps_HeapBufMP_free(ti_sdo_ipc_heaps_HeapBufMP_Object *obj,
Ptr block, SizeT size)

...

Assert_isTrue(((UInt32)block >= (UInt32)obj->buf) &&
((UInt32)block < ((UInt32)obj->buf + obj->blockSize * obj->numBlocks)),
ti_sdo_ipc_heaps_HeapBufMP_A_invBlockFreed);

Creating both heap instances, when they are registered in the queue objects of each processor I use the same blocksize and numblocks, the only difference in the heap setup is the heap (instance) Id and name.

Can anyone give me directions on this? I made this system work, but the original setup uses a shared heap instance for both queues, now for control/optimization issues we are trying to split the model. Maybe I am still missing something.

Many thanks !

Regards

- Jose  Lopez

  • Jose,

    It sounds like you created a separate heap instance on each processor. Unfortunately, you cannot allocate from one heap, send the block to the other processor, and then free the block into the other heap. You must always allocate and free from the same heap instance.

    All the transports provided by SysLink and IPC are based on shared memory. They are designed to only work with a shared heap. In other words, one side will first create a heap instance and register it with MessageQ. Then, the other side will open the same heap instance and register it with MessageQ using the same heap ID.

    You indicate that you want two separate heaps for better performance and control. You can still do this. Try the following setup. Each side will create a separate heap instance (just like you are doing now). Call this the local heap. Use the local heap for all outbound messages. Each processor needs to register its own local heap with MessageQ using a different heap ID. For example, ARM might use heap ID = 1 and DSP might use heap ID = 2.

    In addition to creating the local heap, each processor also needs to open the heap created by the other processor. Call this the remote heap. For example, the ARM would first create its own local heap and then open the heap created by the DSP. The DSP would do the same. It is important to use this order: create your local heap first, then open the remote heap. This avoids a potential deadlock. After opening the remote heap, you must register it with MessageQ using the same heap ID that was used by the creator. For example, if the DSP created a heap and registered it using heap ID = 2, then the ARM must open the DSP heap and register it with MessageQ also using heap ID = 2. The DSP would do the same with the ARM heap.

    Doing this will allocate and free the message from the same heap. But you will have two heaps, one for each direction. It also allows you to create each heap with a different profile. For example, if the ARM sends small messages to the DSP but the DSP sends large messages to the ARM, then each heap can be created as needed.

    ~Ramsey

  • Hello Ramsey, thanks for the reply

    Regarding the heap opening I have an observation:

    The heap opening has been done locally, this is, Processor A has a Queue object and wants to link it with a recently created local Heap (instance), as far as I understand to access a remote heap is more than enough to Open the remote Queue object (MessageQ_open), not the remote heap directly.

    Anyway I think I found the problem, taking a look at MessageQ.h :

    /*..
    * This function registers a heap with MessageQ. The user selects a unique
    * heapId associated with this heap. When a message is allocated via the
    * #MessageQ_alloc function, the heapId is specified. Internally, MessageQ
    * uses the heapId to access the heap.
    ..
    */
    Int MessageQ_registerHeap(Ptr heap, UInt16 heapId);

    The heap you register should be the one you will point to, not the one you have locally. I have to make that change and tell if that solves the problem.

    Regards
    -Jose Lopez
  • Jose,

    Each processor must register both the local heap and the remote heap with MessageQ. First, create the local heap and register it with MessageQ. Then open the remote heap and also register it with MessageQ. Both processors must do this.

    When sending a message, use MessageQ_alloc and pass in the heap ID for the local heap.

    After receiving a messages, simply call MessageQ_free. Internally, the heap ID will be used to return the message to the proper heap.

    ~Ramsey