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.

CC3235SF: Why do I fail to apply for memory with malloc?

Part Number: CC3235SF

When I apply for a piece of memory with malloc function, I find that it is always unsuccessful. Why?

  • Does anyone know how to solve this problem?

  • Hi Yaowu,

    What is the error that you see in CCS? Is emg_send_data_pack the same size as temp?

    Thanks,
    Jacob

  • I applied for memory with malloc, but it returned 0.It seems that malloc memory is not given. What needs to be modified?

  • Hi,

    Why did it malloc fail? Do I need to modify it to malloc?please help me.

  • Hi Yaowu,

    Can you post a picture of the contents of emg_send_data_pack right before the memcpy()? 

    The other thing to check is that your program has heap memory allocated to it. You can make sure this is the case by viewing the heap_size variable in the .cmd.

    For example:

    This picture shows my example has no heap allocated. 

    Thanks,
    Jacob 

  • Hi,

    Yes, it still doesn't work after I set it to blocking mode. Everything is normal before I enter the for() loop, but it doesn't work when I enter for() and use IIC to read data. The program is stuck in IIC.

  • Hi Yaowu,

    I don't think the response you posted above is related to this issue. Can you post a picture of emg_send_data_pack right before the memcpy() and your heap_size variable?

    Thanks,
    Jacob

  • emg_send_data_pack picture

    and heap_size

     

  • Hi Yaowu,

    The malloc is in fact successful. The screenshot you provided with temp above shows the memory address where you have allocated temp and the value at that address. 

    I have allocated 256 bytes to char* a:

    And then after the memcpy:

    The malloc is successful; I recommend using the Memory Browser view in CCS to watch what is allocated at temp's address.

    Thanks,
    Jacob 

  • OK.Thank you Jacob.

  • Hi,

    Why can't I malloc memory in interrupt?

    When I run to malloc, the program gets stuck and stops in the vportentercritical () function.

  • Hi Yaowu,

    I'll follow up next week.

    Thanks,
    Jacob

  • Hi Jacob,

    You know why i can't malloc the memory in interrupt?

  • Hi Yaowu,

    I apologize, I forgot to update my out of office status last week. I will follow up this week.

    Thanks,
    Jacob

  • Hi Yaowu, 

    Sorry for the delay. Do you really need to make the malloc call in the interrupt? I do not advise calling malloc in an interrupt. Malloc accesses the global memory pool that your program uses. If you call malloc from two unsynchronized places, then the memory pool can be impacted negatively. If you absolutely need to call malloc in an interrupt and malloc is being called somewhere else, you need to make sure to wrap the malloc call to be interrupt safe. 

    Instead, I recommend setting a flag in the interrupt to call malloc in your main program. 

    Thanks,
    Jacob

  • Hi Jacob,

    I need to apply for memory in the interrupt, and then release it after use, but when I call malloc function in the interrupt, the program gets stuck here. Is there any way to solve or replace this problem?

    Please help me solve the proplem.

    Thanks.

  • Hi wu,

    I'll follow up later this week.

    Thanks,
    Jacob

  • Hi Jacob,

    I need to malloc a new piece of memory in each interrupt, and then use it in the interrupt and then free it to ensure the integrity of the data.

    Please provide solutions as soon as possible.

    Thanks.

  • Hi wu,

    How big memory you need at interrupt? Do you need send values inside this memory out of your ISR? Why you not increase stack for ISR and use memory at stack?

    Usage of malloc at ISR is not a best ideas. This approach is against all recommendations. At internet you find tons of discussions how bad idea it is.

    Jan

  • Hi Jan,

    I need to malloc a 48 byte memory during each interrupt, then copy the read data to this memory, and then put this memory into the queue for the task to read, so as to ensure that the data generated by each interrupt is complete and continuous, because if an array is used, the data will be overwritten, so I need to malloc memory in the interrupt.

    Thanks.

  • Hi,

    This is a horrible idea, and I am not surprised that its not working. How do you protect your malloc in your ISR from re-rentering? Why you not allocate memory for you message queue outside ISR? Why you not using something more efficient like a memory pool?

    Resources required for malloc are extensive. You need to realise that you are working with 80MHz MCU not computer with GHz CPU and tons of RAM.

    Jan

  • Hi Jan,

    Because a pointer is passed in the message queue, if an array is used to pass data, it is easy to cause the data to be overwritten before it is read from the queue. Or do you have any good suggestions to replace this method of interrupting malloc memory?

    Thanks.

  • Hi,

    Maybe code inside ISR looks with malloc() simple and clean, but this is way to hell. It seems you not realize how many CPU cycles cost you simple malloc() call and you will be surprised how it ruins time behaviour of your application.

    I don't see any reason why usage memory for your queue allocated outside ISR should be related to overwritten of unprocessed data. There is no difference when malloc() does not have enough space inside heap or memory for message queue is full.

    Memory pool object is one of ways how to allocate memory faster. But still is better to avoid dynamic memory allocation inside ISR.

    Jan

  • Hi Jan,

    How to allocate queue memory other than ISR? I used MQ in interrupt_ Send() sends the read data to the queue.
    You may say that you set the flag bit in the interrupt and then perform data reading and sending in the task, but how to ensure that when the flag bit is set in the interrupt, you go to the task to perform data reading and sending? The time of task scheduling is uncertain, which may lead to interruption of data reading and sending for several times.

    Thanks.

  • Hi,

    Sorry I don't understand. What prevent you to allocate memory for your message queue outside ISR before is used? Personally I don't use FreeRTOS but TI-RTOS and ThreadX at many different projects. I use queue with ISR by that exact way.

    Jan

  • Hi,

    int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len,unsigned int msg_prio);

    mq_ Send () only sends the first address of the stored data to the queue, not all the data are sent to the queue one by one. How can I ensure that the data in the queue will not be modified before being consumed each time?

    How to ensure that the first address of the data sent to the queue is a new space before the data is consumed?

    Thanks.

  • Hi,

    And you how have created queue for pointers only? Why not for whole 48B. Please see FreeRTOS documentation for Queue.

    Jan

  • Hi,

    This is the queue I created according to the routine, Does the mq_send () function copy the data directly into the queue or just copy the first address where the data is stored into the queue?

    Thanks.

  • Hi,

    It copy what you provide. TI-RTOS or FreeRTOS can use message queue with "any" size of message, but for example ThreadX have limitation to 16B.

    int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
            unsigned int msg_prio)
    {
        MQueueDesc *mqd = (MQueueDesc *)mqdes;
        MQueueObj  *msgQueue = mqd->msgQueue;
        BaseType_t  status;
        TickType_t  timeout;
    
        if (msg_len > (size_t)(msgQueue->attrs.mq_msgsize)) {
            if (!HwiP_inISR()) {
                errno = EMSGSIZE;
            }
            return (-1);
        }
    
        /*
         *  If O_NONBLOCK is not set, block until space is available in the
         *  queue.  Otherwise, return -1 if no space is available.
         */
        if (mqd->flags & O_NONBLOCK) {
            timeout = 0;
        }
        else {
            timeout = portMAX_DELAY;
        }
    
        if (HwiP_inISR()) {
            status = xQueueSendFromISR(msgQueue->queue, msg_ptr, NULL);
        }
        else {
            status = xQueueSend(msgQueue->queue, msg_ptr, timeout);
        }
    
        if (status != pdTRUE) {
            if (!HwiP_inISR()) {
                errno = EAGAIN;
            }
            return (-1);
        }
    
        return (0);
    }

    Jan